PluginProbe
TablePress – Tables in WordPress made easy / 2.2.1
TablePress – Tables in WordPress made easy v2.2.1
3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 2.4.4 All 44 releases
tablepress / libraries / vendor / Complex / Functions.php

Functions.php in TablePress – Tables in WordPress made easy 2.2.1, at libraries/vendor/Complex/Functions.php

824 lines 28.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\Complex;
4
5 use InvalidArgumentException;
6
7 class Functions
8 {
9 /**
10 * Returns the absolute value (modulus) of a complex number.
11 * Also known as the rho of the complex number, i.e. the distance/radius
12 * from the centrepoint to the representation of the number in polar coordinates.
13 *
14 * This function is a synonym for rho()
15 *
16 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
17 * @return float The absolute (or rho) value of the complex argument.
18 * @throws Exception If argument isn't a valid real or complex number.
19 *
20 * @see rho
21 *
22 */
23 public static function abs($complex): float
24 {
25 return self::rho($complex);
26 }
27
28 /**
29 * Returns the inverse cosine of a complex number.
30 *
31 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
32 * @return TablePress\Complex The inverse cosine of the complex argument.
33 * @throws Exception If argument isn't a valid real or complex number.
34 */
35 public static function acos($complex): TablePress\Complex
36 {
37 $complex = Complex::validateComplexArgument($complex);
38
39 $invsqrt = self::sqrt(Operations::subtract(1, Operations::multiply($complex, $complex)));
40 $adjust = new Complex(
41 $complex->getReal() - $invsqrt->getImaginary(),
42 $complex->getImaginary() + $invsqrt->getReal()
43 );
44 $log = self::ln($adjust);
45
46 return new Complex(
47 $log->getImaginary(),
48 -1 * $log->getReal()
49 );
50 }
51
52 /**
53 * Returns the inverse hyperbolic cosine of a complex number.
54 *
55 * Formula from Wolfram Alpha:
56 * cosh^(-1)z = ln(z + sqrt(z + 1) sqrt(z - 1)).
57 *
58 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
59 * @return TablePress\Complex The inverse hyperbolic cosine of the complex argument.
60 * @throws Exception If argument isn't a valid real or complex number.
61 */
62 public static function acosh($complex): TablePress\Complex
63 {
64 $complex = Complex::validateComplexArgument($complex);
65
66 if ($complex->isReal() && ($complex->getReal() > 1)) {
67 return new Complex(\acosh($complex->getReal()));
68 }
69
70 $acosh = self::ln(
71 Operations::add(
72 $complex,
73 Operations::multiply(
74 self::sqrt(Operations::add($complex, 1)),
75 self::sqrt(Operations::subtract($complex, 1))
76 )
77 )
78 );
79
80 return $acosh;
81 }
82
83 /**
84 * Returns the inverse cotangent of a complex number.
85 *
86 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
87 * @return TablePress\Complex The inverse cotangent of the complex argument.
88 * @throws Exception If argument isn't a valid real or complex number.
89 * @throws \InvalidArgumentException If function would result in a division by zero
90 */
91 public static function acot($complex): TablePress\Complex
92 {
93 $complex = Complex::validateComplexArgument($complex);
94
95 return self::atan(self::inverse($complex));
96 }
97
98 /**
99 * Returns the inverse hyperbolic cotangent of a complex number.
100 *
101 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
102 * @return TablePress\Complex The inverse hyperbolic cotangent of the complex argument.
103 * @throws Exception If argument isn't a valid real or complex number.
104 * @throws \InvalidArgumentException If function would result in a division by zero
105 */
106 public static function acoth($complex): TablePress\Complex
107 {
108 $complex = Complex::validateComplexArgument($complex);
109
110 return self::atanh(self::inverse($complex));
111 }
112
113 /**
114 * Returns the inverse cosecant of a complex number.
115 *
116 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
117 * @return TablePress\Complex The inverse cosecant of the complex argument.
118 * @throws Exception If argument isn't a valid real or complex number.
119 * @throws \InvalidArgumentException If function would result in a division by zero
120 */
121 public static function acsc($complex): TablePress\Complex
122 {
123 $complex = Complex::validateComplexArgument($complex);
124
125 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
126 return new Complex(INF);
127 }
128
129 return self::asin(self::inverse($complex));
130 }
131
132 /**
133 * Returns the inverse hyperbolic cosecant of a complex number.
134 *
135 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
136 * @return TablePress\Complex The inverse hyperbolic cosecant of the complex argument.
137 * @throws Exception If argument isn't a valid real or complex number.
138 * @throws \InvalidArgumentException If function would result in a division by zero
139 */
140 public static function acsch($complex): TablePress\Complex
141 {
142 $complex = Complex::validateComplexArgument($complex);
143
144 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
145 return new Complex(INF);
146 }
147
148 return self::asinh(self::inverse($complex));
149 }
150
151 /**
152 * Returns the argument of a complex number.
153 * Also known as the theta of the complex number, i.e. the angle in radians
154 * from the real axis to the representation of the number in polar coordinates.
155 *
156 * This function is a synonym for theta()
157 *
158 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
159 * @return float The argument (or theta) value of the complex argument.
160 * @throws Exception If argument isn't a valid real or complex number.
161 *
162 * @see theta
163 */
164 public static function argument($complex): float
165 {
166 return self::theta($complex);
167 }
168
169 /**
170 * Returns the inverse secant of a complex number.
171 *
172 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
173 * @return TablePress\Complex The inverse secant of the complex argument.
174 * @throws Exception If argument isn't a valid real or complex number.
175 * @throws \InvalidArgumentException If function would result in a division by zero
176 */
177 public static function asec($complex): TablePress\Complex
178 {
179 $complex = Complex::validateComplexArgument($complex);
180
181 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
182 return new Complex(INF);
183 }
184
185 return self::acos(self::inverse($complex));
186 }
187
188 /**
189 * Returns the inverse hyperbolic secant of a complex number.
190 *
191 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
192 * @return TablePress\Complex The inverse hyperbolic secant of the complex argument.
193 * @throws Exception If argument isn't a valid real or complex number.
194 * @throws \InvalidArgumentException If function would result in a division by zero
195 */
196 public static function asech($complex): TablePress\Complex
197 {
198 $complex = Complex::validateComplexArgument($complex);
199
200 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
201 return new Complex(INF);
202 }
203
204 return self::acosh(self::inverse($complex));
205 }
206
207 /**
208 * Returns the inverse sine of a complex number.
209 *
210 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
211 * @return TablePress\Complex The inverse sine of the complex argument.
212 * @throws Exception If argument isn't a valid real or complex number.
213 */
214 public static function asin($complex): TablePress\Complex
215 {
216 $complex = Complex::validateComplexArgument($complex);
217
218 $invsqrt = self::sqrt(Operations::subtract(1, Operations::multiply($complex, $complex)));
219 $adjust = new Complex(
220 $invsqrt->getReal() - $complex->getImaginary(),
221 $invsqrt->getImaginary() + $complex->getReal()
222 );
223 $log = self::ln($adjust);
224
225 return new Complex(
226 $log->getImaginary(),
227 -1 * $log->getReal()
228 );
229 }
230
231 /**
232 * Returns the inverse hyperbolic sine of a complex number.
233 *
234 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
235 * @return TablePress\Complex The inverse hyperbolic sine of the complex argument.
236 * @throws Exception If argument isn't a valid real or complex number.
237 */
238 public static function asinh($complex): TablePress\Complex
239 {
240 $complex = Complex::validateComplexArgument($complex);
241
242 if ($complex->isReal() && ($complex->getReal() > 1)) {
243 return new Complex(\asinh($complex->getReal()));
244 }
245
246 $asinh = clone $complex;
247 $asinh = $asinh->reverse()
248 ->invertReal();
249 $asinh = self::asin($asinh);
250
251 return $asinh->reverse()
252 ->invertImaginary();
253 }
254
255 /**
256 * Returns the inverse tangent of a complex number.
257 *
258 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
259 * @return TablePress\Complex The inverse tangent of the complex argument.
260 * @throws Exception If argument isn't a valid real or complex number.
261 * @throws \InvalidArgumentException If function would result in a division by zero
262 */
263 public static function atan($complex): TablePress\Complex
264 {
265 $complex = Complex::validateComplexArgument($complex);
266
267 if ($complex->isReal()) {
268 return new Complex(\atan($complex->getReal()));
269 }
270
271 $t1Value = new Complex(-1 * $complex->getImaginary(), $complex->getReal());
272 $uValue = new Complex(1, 0);
273
274 $d1Value = clone $uValue;
275 $d1Value = Operations::subtract($d1Value, $t1Value);
276 $d2Value = Operations::add($t1Value, $uValue);
277 $uResult = $d1Value->divideBy($d2Value);
278 $uResult = self::ln($uResult);
279
280 $realMultiplier = -0.5;
281 $imaginaryMultiplier = 0.5;
282
283 if (abs($uResult->getImaginary()) === M_PI) {
284 // If we have an imaginary value at the max or min (PI or -PI), then we need to ensure
285 // that the primary is assigned for the correct quadrant.
286 $realMultiplier = (
287 ($uResult->getImaginary() === M_PI && $uResult->getReal() > 0.0) ||
288 ($uResult->getImaginary() === -M_PI && $uResult->getReal() < 0.0)
289 ) ? 0.5 : -0.5;
290 }
291
292 return new Complex(
293 $uResult->getImaginary() * $realMultiplier,
294 $uResult->getReal() * $imaginaryMultiplier,
295 $complex->getSuffix()
296 );
297 }
298
299 /**
300 * Returns the inverse hyperbolic tangent of a complex number.
301 *
302 * Formula from Wolfram Alpha:
303 * tanh^(-1)z = 1/2 [ln(1 + z) - ln(1 - z)].
304 *
305 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
306 * @return TablePress\Complex The inverse hyperbolic tangent of the complex argument.
307 * @throws Exception If argument isn't a valid real or complex number.
308 */
309 public static function atanh($complex): TablePress\Complex
310 {
311 $complex = Complex::validateComplexArgument($complex);
312
313 if ($complex->isReal()) {
314 $real = $complex->getReal();
315 if ($real >= -1.0 && $real <= 1.0) {
316 return new Complex(\atanh($real));
317 } else {
318 return new Complex(\atanh(1 / $real), (($real < 0.0) ? M_PI_2 : -1 * M_PI_2));
319 }
320 }
321
322 $atanh = Operations::multiply(
323 Operations::subtract(
324 self::ln(Operations::add(1.0, $complex)),
325 self::ln(Operations::subtract(1.0, $complex))
326 ),
327 0.5
328 );
329
330 return $atanh;
331 }
332
333 /**
334 * Returns the complex conjugate of a complex number
335 *
336 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
337 * @return TablePress\Complex The conjugate of the complex argument.
338 * @throws Exception If argument isn't a valid real or complex number.
339 */
340 public static function conjugate($complex): TablePress\Complex
341 {
342 $complex = Complex::validateComplexArgument($complex);
343
344 return new Complex(
345 $complex->getReal(),
346 -1 * $complex->getImaginary(),
347 $complex->getSuffix()
348 );
349 }
350
351 /**
352 * Returns the cosine of a complex number.
353 *
354 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
355 * @return TablePress\Complex The cosine of the complex argument.
356 * @throws Exception If argument isn't a valid real or complex number.
357 */
358 public static function cos($complex): TablePress\Complex
359 {
360 $complex = Complex::validateComplexArgument($complex);
361
362 if ($complex->isReal()) {
363 return new Complex(\cos($complex->getReal()));
364 }
365
366 return self::conjugate(
367 new Complex(
368 \cos($complex->getReal()) * \cosh($complex->getImaginary()),
369 \sin($complex->getReal()) * \sinh($complex->getImaginary()),
370 $complex->getSuffix()
371 )
372 );
373 }
374
375 /**
376 * Returns the hyperbolic cosine of a complex number.
377 *
378 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
379 * @return TablePress\Complex The hyperbolic cosine of the complex argument.
380 * @throws Exception If argument isn't a valid real or complex number.
381 */
382 public static function cosh($complex): TablePress\Complex
383 {
384 $complex = Complex::validateComplexArgument($complex);
385
386 if ($complex->isReal()) {
387 return new Complex(\cosh($complex->getReal()));
388 }
389
390 return new Complex(
391 \cosh($complex->getReal()) * \cos($complex->getImaginary()),
392 \sinh($complex->getReal()) * \sin($complex->getImaginary()),
393 $complex->getSuffix()
394 );
395 }
396
397 /**
398 * Returns the cotangent of a complex number.
399 *
400 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
401 * @return TablePress\Complex The cotangent of the complex argument.
402 * @throws Exception If argument isn't a valid real or complex number.
403 * @throws \InvalidArgumentException If function would result in a division by zero
404 */
405 public static function cot($complex): TablePress\Complex
406 {
407 $complex = Complex::validateComplexArgument($complex);
408
409 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
410 return new Complex(INF);
411 }
412
413 return self::inverse(self::tan($complex));
414 }
415
416 /**
417 * Returns the hyperbolic cotangent of a complex number.
418 *
419 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
420 * @return TablePress\Complex The hyperbolic cotangent of the complex argument.
421 * @throws Exception If argument isn't a valid real or complex number.
422 * @throws \InvalidArgumentException If function would result in a division by zero
423 */
424 public static function coth($complex): TablePress\Complex
425 {
426 $complex = Complex::validateComplexArgument($complex);
427
428 return self::inverse(self::tanh($complex));
429 }
430
431 /**
432 * Returns the cosecant of a complex number.
433 *
434 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
435 * @return TablePress\Complex The cosecant of the complex argument.
436 * @throws Exception If argument isn't a valid real or complex number.
437 * @throws \InvalidArgumentException If function would result in a division by zero
438 */
439 public static function csc($complex): TablePress\Complex
440 {
441 $complex = Complex::validateComplexArgument($complex);
442
443 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
444 return new Complex(INF);
445 }
446
447 return self::inverse(self::sin($complex));
448 }
449
450 /**
451 * Returns the hyperbolic cosecant of a complex number.
452 *
453 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
454 * @return TablePress\Complex The hyperbolic cosecant of the complex argument.
455 * @throws Exception If argument isn't a valid real or complex number.
456 * @throws \InvalidArgumentException If function would result in a division by zero
457 */
458 public static function csch($complex): TablePress\Complex
459 {
460 $complex = Complex::validateComplexArgument($complex);
461
462 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
463 return new Complex(INF);
464 }
465
466 return self::inverse(self::sinh($complex));
467 }
468
469 /**
470 * Returns the exponential of a complex number.
471 *
472 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
473 * @return TablePress\Complex The exponential of the complex argument.
474 * @throws Exception If argument isn't a valid real or complex number.
475 */
476 public static function exp($complex): TablePress\Complex
477 {
478 $complex = Complex::validateComplexArgument($complex);
479
480 if (($complex->getReal() == 0.0) && (\abs($complex->getImaginary()) == M_PI)) {
481 return new Complex(-1.0, 0.0);
482 }
483
484 $rho = \exp($complex->getReal());
485
486 return new Complex(
487 $rho * \cos($complex->getImaginary()),
488 $rho * \sin($complex->getImaginary()),
489 $complex->getSuffix()
490 );
491 }
492
493 /**
494 * Returns the inverse of a complex number.
495 *
496 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
497 * @return TablePress\Complex The inverse of the complex argument.
498 * @throws Exception If argument isn't a valid real or complex number.
499 * @throws InvalidArgumentException If function would result in a division by zero
500 */
501 public static function inverse($complex): TablePress\Complex
502 {
503 $complex = clone Complex::validateComplexArgument($complex);
504
505 if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) {
506 throw new InvalidArgumentException('Division by zero');
507 }
508
509 return $complex->divideInto(1.0);
510 }
511
512 /**
513 * Returns the natural logarithm of a complex number.
514 *
515 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
516 * @return TablePress\Complex The natural logarithm of the complex argument.
517 * @throws Exception If argument isn't a valid real or complex number.
518 * @throws InvalidArgumentException If the real and the imaginary parts are both zero
519 */
520 public static function ln($complex): TablePress\Complex
521 {
522 $complex = Complex::validateComplexArgument($complex);
523
524 if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
525 throw new InvalidArgumentException();
526 }
527
528 return new Complex(
529 \log(self::rho($complex)),
530 self::theta($complex),
531 $complex->getSuffix()
532 );
533 }
534
535 /**
536 * Returns the base-2 logarithm of a complex number.
537 *
538 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
539 * @return TablePress\Complex The base-2 logarithm of the complex argument.
540 * @throws Exception If argument isn't a valid real or complex number.
541 * @throws InvalidArgumentException If the real and the imaginary parts are both zero
542 */
543 public static function log2($complex): TablePress\Complex
544 {
545 $complex = Complex::validateComplexArgument($complex);
546
547 if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
548 throw new InvalidArgumentException();
549 } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {
550 return new Complex(\log($complex->getReal(), 2), 0.0, $complex->getSuffix());
551 }
552
553 return self::ln($complex)
554 ->multiply(\log(Complex::EULER, 2));
555 }
556
557 /**
558 * Returns the common logarithm (base 10) of a complex number.
559 *
560 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
561 * @return TablePress\Complex The common logarithm (base 10) of the complex argument.
562 * @throws Exception If argument isn't a valid real or complex number.
563 * @throws InvalidArgumentException If the real and the imaginary parts are both zero
564 */
565 public static function log10($complex): TablePress\Complex
566 {
567 $complex = Complex::validateComplexArgument($complex);
568
569 if (($complex->getReal() == 0.0) && ($complex->getImaginary() == 0.0)) {
570 throw new InvalidArgumentException();
571 } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) {
572 return new Complex(\log10($complex->getReal()), 0.0, $complex->getSuffix());
573 }
574
575 return self::ln($complex)
576 ->multiply(\log10(Complex::EULER));
577 }
578
579 /**
580 * Returns the negative of a complex number.
581 *
582 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
583 * @return TablePress\Complex The negative value of the complex argument.
584 * @throws Exception If argument isn't a valid real or complex number.
585 *
586 * @see rho
587 *
588 */
589 public static function negative($complex): TablePress\Complex
590 {
591 $complex = Complex::validateComplexArgument($complex);
592
593 return new Complex(
594 -1 * $complex->getReal(),
595 -1 * $complex->getImaginary(),
596 $complex->getSuffix()
597 );
598 }
599
600 /**
601 * Returns a complex number raised to a power.
602 *
603 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
604 * @param float|integer $power The power to raise this value to
605 * @return TablePress\Complex The complex argument raised to the real power.
606 * @throws Exception If the power argument isn't a valid real
607 */
608 public static function pow($complex, $power): TablePress\Complex
609 {
610 $complex = Complex::validateComplexArgument($complex);
611
612 if (!is_numeric($power)) {
613 throw new Exception('Power argument must be a real number');
614 }
615
616 if ($complex->getImaginary() == 0.0 && $complex->getReal() >= 0.0) {
617 return new Complex(\pow($complex->getReal(), $power));
618 }
619
620 $rValue = \sqrt(($complex->getReal() * $complex->getReal()) + ($complex->getImaginary() * $complex->getImaginary()));
621 $rPower = \pow($rValue, $power);
622 $theta = $complex->argument() * $power;
623 if ($theta == 0) {
624 return new Complex(1);
625 }
626
627 return new Complex($rPower * \cos($theta), $rPower * \sin($theta), $complex->getSuffix());
628 }
629
630 /**
631 * Returns the rho of a complex number.
632 * This is the distance/radius from the centrepoint to the representation of the number in polar coordinates.
633 *
634 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
635 * @return float The rho value of the complex argument.
636 * @throws Exception If argument isn't a valid real or complex number.
637 */
638 public static function rho($complex): float
639 {
640 $complex = Complex::validateComplexArgument($complex);
641
642 return \sqrt(
643 ($complex->getReal() * $complex->getReal()) +
644 ($complex->getImaginary() * $complex->getImaginary())
645 );
646 }
647
648 /**
649 * Returns the secant of a complex number.
650 *
651 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
652 * @return TablePress\Complex The secant of the complex argument.
653 * @throws Exception If argument isn't a valid real or complex number.
654 * @throws \InvalidArgumentException If function would result in a division by zero
655 */
656 public static function sec($complex): TablePress\Complex
657 {
658 $complex = Complex::validateComplexArgument($complex);
659
660 return self::inverse(self::cos($complex));
661 }
662
663 /**
664 * Returns the hyperbolic secant of a complex number.
665 *
666 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
667 * @return TablePress\Complex The hyperbolic secant of the complex argument.
668 * @throws Exception If argument isn't a valid real or complex number.
669 * @throws \InvalidArgumentException If function would result in a division by zero
670 */
671 public static function sech($complex): TablePress\Complex
672 {
673 $complex = Complex::validateComplexArgument($complex);
674
675 return self::inverse(self::cosh($complex));
676 }
677
678 /**
679 * Returns the sine of a complex number.
680 *
681 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
682 * @return TablePress\Complex The sine of the complex argument.
683 * @throws Exception If argument isn't a valid real or complex number.
684 */
685 public static function sin($complex): TablePress\Complex
686 {
687 $complex = Complex::validateComplexArgument($complex);
688
689 if ($complex->isReal()) {
690 return new Complex(\sin($complex->getReal()));
691 }
692
693 return new Complex(
694 \sin($complex->getReal()) * \cosh($complex->getImaginary()),
695 \cos($complex->getReal()) * \sinh($complex->getImaginary()),
696 $complex->getSuffix()
697 );
698 }
699
700 /**
701 * Returns the hyperbolic sine of a complex number.
702 *
703 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
704 * @return TablePress\Complex The hyperbolic sine of the complex argument.
705 * @throws Exception If argument isn't a valid real or complex number.
706 */
707 public static function sinh($complex): TablePress\Complex
708 {
709 $complex = Complex::validateComplexArgument($complex);
710
711 if ($complex->isReal()) {
712 return new Complex(\sinh($complex->getReal()));
713 }
714
715 return new Complex(
716 \sinh($complex->getReal()) * \cos($complex->getImaginary()),
717 \cosh($complex->getReal()) * \sin($complex->getImaginary()),
718 $complex->getSuffix()
719 );
720 }
721
722 /**
723 * Returns the square root of a complex number.
724 *
725 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
726 * @return TablePress\Complex The Square root of the complex argument.
727 * @throws Exception If argument isn't a valid real or complex number.
728 */
729 public static function sqrt($complex): TablePress\Complex
730 {
731 $complex = Complex::validateComplexArgument($complex);
732
733 $theta = self::theta($complex);
734 $delta1 = \cos($theta / 2);
735 $delta2 = \sin($theta / 2);
736 $rho = \sqrt(self::rho($complex));
737
738 return new Complex($delta1 * $rho, $delta2 * $rho, $complex->getSuffix());
739 }
740
741 /**
742 * Returns the tangent of a complex number.
743 *
744 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
745 * @return TablePress\Complex The tangent of the complex argument.
746 * @throws Exception If argument isn't a valid real or complex number.
747 * @throws InvalidArgumentException If function would result in a division by zero
748 */
749 public static function tan($complex): TablePress\Complex
750 {
751 $complex = Complex::validateComplexArgument($complex);
752
753 if ($complex->isReal()) {
754 return new Complex(\tan($complex->getReal()));
755 }
756
757 $real = $complex->getReal();
758 $imaginary = $complex->getImaginary();
759 $divisor = 1 + \pow(\tan($real), 2) * \pow(\tanh($imaginary), 2);
760 if ($divisor == 0.0) {
761 throw new InvalidArgumentException('Division by zero');
762 }
763
764 return new Complex(
765 \pow(self::sech($imaginary)->getReal(), 2) * \tan($real) / $divisor,
766 \pow(self::sec($real)->getReal(), 2) * \tanh($imaginary) / $divisor,
767 $complex->getSuffix()
768 );
769 }
770
771 /**
772 * Returns the hyperbolic tangent of a complex number.
773 *
774 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
775 * @return TablePress\Complex The hyperbolic tangent of the complex argument.
776 * @throws Exception If argument isn't a valid real or complex number.
777 * @throws \InvalidArgumentException If function would result in a division by zero
778 */
779 public static function tanh($complex): TablePress\Complex
780 {
781 $complex = Complex::validateComplexArgument($complex);
782 $real = $complex->getReal();
783 $imaginary = $complex->getImaginary();
784 $divisor = \cos($imaginary) * \cos($imaginary) + \sinh($real) * \sinh($real);
785 if ($divisor == 0.0) {
786 throw new InvalidArgumentException('Division by zero');
787 }
788
789 return new Complex(
790 \sinh($real) * \cosh($real) / $divisor,
791 0.5 * \sin(2 * $imaginary) / $divisor,
792 $complex->getSuffix()
793 );
794 }
795
796 /**
797 * Returns the theta of a complex number.
798 * This is the angle in radians from the real axis to the representation of the number in polar coordinates.
799 *
800 * @param TablePress\Complex|mixed $complex TablePress\Complex number or a numeric value.
801 * @return float The theta value of the complex argument.
802 * @throws Exception If argument isn't a valid real or complex number.
803 */
804 public static function theta($complex): float
805 {
806 $complex = Complex::validateComplexArgument($complex);
807
808 if ($complex->getReal() == 0.0) {
809 if ($complex->isReal()) {
810 return 0.0;
811 } elseif ($complex->getImaginary() < 0.0) {
812 return M_PI / -2;
813 }
814 return M_PI / 2;
815 } elseif ($complex->getReal() > 0.0) {
816 return \atan($complex->getImaginary() / $complex->getReal());
817 } elseif ($complex->getImaginary() < 0.0) {
818 return -(M_PI - \atan(\abs($complex->getImaginary()) / \abs($complex->getReal())));
819 }
820
821 return M_PI - \atan($complex->getImaginary() / \abs($complex->getReal()));
822 }
823 }
824