Complex.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. class Complex
  3. {
  4. private $realPart = 0;
  5. private $imaginaryPart = 0;
  6. private $suffix = null;
  7. public static function _parseComplex($complexNumber)
  8. {
  9. // Test for real number, with no imaginary part
  10. if (is_numeric($complexNumber)) {
  11. return array($complexNumber, 0, null);
  12. }
  13. // Fix silly human errors
  14. if (strpos($complexNumber, '+-') !== false) {
  15. $complexNumber = str_replace('+-', '-', $complexNumber);
  16. }
  17. if (strpos($complexNumber, '++') !== false) {
  18. $complexNumber = str_replace('++', '+', $complexNumber);
  19. }
  20. if (strpos($complexNumber, '--') !== false) {
  21. $complexNumber = str_replace('--', '-', $complexNumber);
  22. }
  23. // Basic validation of string, to parse out real and imaginary parts, and any suffix
  24. $validComplex = preg_match('/^([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)([\-\+]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?)?(([\-\+]?)([ij]?))$/ui', $complexNumber, $complexParts);
  25. if (!$validComplex) {
  26. // Neither real nor imaginary part, so test to see if we actually have a suffix
  27. $validComplex = preg_match('/^([\-\+]?)([ij])$/ui', $complexNumber, $complexParts);
  28. if (!$validComplex) {
  29. throw new Exception('COMPLEX: Invalid complex number');
  30. }
  31. // We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)
  32. $imaginary = 1;
  33. if ($complexParts[1] === '-') {
  34. $imaginary = 0 - $imaginary;
  35. }
  36. return array(0, $imaginary, $complexParts[2]);
  37. }
  38. // If we don't have an imaginary part, identify whether it should be +1 or -1...
  39. if (($complexParts[4] === '') && ($complexParts[9] !== '')) {
  40. if ($complexParts[7] !== $complexParts[9]) {
  41. $complexParts[4] = 1;
  42. if ($complexParts[8] === '-') {
  43. $complexParts[4] = -1;
  44. }
  45. // ... or if we have only the real and no imaginary part (in which case our real should be the imaginary)
  46. } else {
  47. $complexParts[4] = $complexParts[1];
  48. $complexParts[1] = 0;
  49. }
  50. }
  51. // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily
  52. return array($complexParts[1], $complexParts[4], !empty($complexParts[9]) ? $complexParts[9] : 'i');
  53. } // function _parseComplex()
  54. public function __construct($realPart, $imaginaryPart = null, $suffix = 'i')
  55. {
  56. if ($imaginaryPart === null) {
  57. if (is_array($realPart)) {
  58. // We have an array of (potentially) real and imaginary parts, and any suffix
  59. list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i');
  60. } elseif ((is_string($realPart)) || (is_numeric($realPart))) {
  61. // We've been given a string to parse to extract the real and imaginary parts, and any suffix
  62. list ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart);
  63. }
  64. }
  65. // Set parsed values in our properties
  66. $this->realPart = (float) $realPart;
  67. $this->imaginaryPart = (float) $imaginaryPart;
  68. $this->suffix = strtolower($suffix);
  69. }
  70. public function getReal()
  71. {
  72. return $this->realPart;
  73. }
  74. public function getImaginary()
  75. {
  76. return $this->imaginaryPart;
  77. }
  78. public function getSuffix()
  79. {
  80. return $this->suffix;
  81. }
  82. public function __toString()
  83. {
  84. $str = "";
  85. if ($this->imaginaryPart != 0.0) {
  86. if (abs($this->imaginaryPart) != 1.0) {
  87. $str .= $this->imaginaryPart . $this->suffix;
  88. } else {
  89. $str .= (($this->imaginaryPart < 0.0) ? '-' : ''). $this->suffix;
  90. }
  91. }
  92. if ($this->realPart != 0.0) {
  93. if (($str) && ($this->imaginaryPart > 0.0)) {
  94. $str = "+" . $str;
  95. }
  96. $str = $this->realPart . $str;
  97. }
  98. if (!$str) {
  99. $str = "0.0";
  100. }
  101. return $str;
  102. }
  103. }