PluginProbe
TablePress – Tables in WordPress made easy / 3.0
TablePress – Tables in WordPress made easy v3.0
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 / Complex.php

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

389 lines 9.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 *
5 * Class for the management of TablePress\Complex numbers
6 *
7 * @copyright Copyright (c) 2013-2018 Mark Baker (https://github.com/MarkBaker/PHPComplex)
8 * @license https://opensource.org/licenses/MIT MIT
9 */
10 namespace TablePress\Complex;
11
12 /**
13 * TablePress\Complex Number object.
14 *
15 * @package TablePress\Complex
16 *
17 * @method float abs()
18 * @method TablePress\Complex acos()
19 * @method TablePress\Complex acosh()
20 * @method TablePress\Complex acot()
21 * @method TablePress\Complex acoth()
22 * @method TablePress\Complex acsc()
23 * @method TablePress\Complex acsch()
24 * @method float argument()
25 * @method TablePress\Complex asec()
26 * @method TablePress\Complex asech()
27 * @method TablePress\Complex asin()
28 * @method TablePress\Complex asinh()
29 * @method TablePress\Complex atan()
30 * @method TablePress\Complex atanh()
31 * @method TablePress\Complex conjugate()
32 * @method TablePress\Complex cos()
33 * @method TablePress\Complex cosh()
34 * @method TablePress\Complex cot()
35 * @method TablePress\Complex coth()
36 * @method TablePress\Complex csc()
37 * @method TablePress\Complex csch()
38 * @method TablePress\Complex exp()
39 * @method TablePress\Complex inverse()
40 * @method TablePress\Complex ln()
41 * @method TablePress\Complex log2()
42 * @method TablePress\Complex log10()
43 * @method TablePress\Complex negative()
44 * @method TablePress\Complex pow(int|float $power)
45 * @method float rho()
46 * @method TablePress\Complex sec()
47 * @method TablePress\Complex sech()
48 * @method TablePress\Complex sin()
49 * @method TablePress\Complex sinh()
50 * @method TablePress\Complex sqrt()
51 * @method TablePress\Complex tan()
52 * @method TablePress\Complex tanh()
53 * @method float theta()
54 * @method TablePress\Complex add(...$complexValues)
55 * @method TablePress\Complex subtract(...$complexValues)
56 * @method TablePress\Complex multiply(...$complexValues)
57 * @method TablePress\Complex divideby(...$complexValues)
58 * @method TablePress\Complex divideinto(...$complexValues)
59 */
60 class Complex
61 {
62 /**
63 * @constant Euler's Number.
64 */
65 const EULER = 2.7182818284590452353602874713526624977572;
66
67 /**
68 * @constant Regexp to split an input string into real and imaginary components and suffix
69 */
70 const NUMBER_SPLIT_REGEXP =
71 '` ^
72 ( # Real part
73 [-+]?(\d+\.?\d*|\d*\.?\d+) # Real value (integer or float)
74 ([Ee][-+]?[0-2]?\d{1,3})? # Optional real exponent for scientific format
75 )
76 ( # Imaginary part
77 [-+]?(\d+\.?\d*|\d*\.?\d+) # Imaginary value (integer or float)
78 ([Ee][-+]?[0-2]?\d{1,3})? # Optional imaginary exponent for scientific format
79 )?
80 ( # Imaginary part is optional
81 ([-+]?) # Imaginary (implicit 1 or -1) only
82 ([ij]?) # Imaginary i or j - depending on whether mathematical or engineering
83 )
84 $`uix';
85
86 /**
87 * @var float $realPart The value of of this complex number on the real plane.
88 */
89 protected $realPart = 0.0;
90
91 /**
92 * @var float $imaginaryPart The value of of this complex number on the imaginary plane.
93 */
94 protected $imaginaryPart = 0.0;
95
96 /**
97 * @var string $suffix The suffix for this complex number (i or j).
98 */
99 protected $suffix;
100
101
102 /**
103 * Validates whether the argument is a valid complex number, converting scalar or array values if possible
104 *
105 * @param mixed $complexNumber The value to parse
106 * @return array
107 * @throws Exception If the argument isn't a TablePress\Complex number or cannot be converted to one
108 */
109 private static function parseComplex($complexNumber)
110 {
111 // Test for real number, with no imaginary part
112 if (is_numeric($complexNumber)) {
113 return [$complexNumber, 0, null];
114 }
115
116 // Fix silly human errors
117 $complexNumber = str_replace(
118 ['+-', '-+', '++', '--'],
119 ['-', '-', '+', '+'],
120 $complexNumber
121 );
122
123 // Basic validation of string, to parse out real and imaginary parts, and any suffix
124 $validComplex = preg_match(
125 self::NUMBER_SPLIT_REGEXP,
126 $complexNumber,
127 $complexParts
128 );
129
130 if (!$validComplex) {
131 // Neither real nor imaginary part, so test to see if we actually have a suffix
132 $validComplex = preg_match('/^([\-\+]?)([ij])$/ui', $complexNumber, $complexParts);
133 if (!$validComplex) {
134 throw new Exception('Invalid complex number');
135 }
136 // We have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)
137 $imaginary = 1;
138 if ($complexParts[1] === '-') {
139 $imaginary = 0 - $imaginary;
140 }
141 return [0, $imaginary, $complexParts[2]];
142 }
143
144 // If we don't have an imaginary part, identify whether it should be +1 or -1...
145 if (($complexParts[4] === '') && ($complexParts[9] !== '')) {
146 if ($complexParts[7] !== $complexParts[9]) {
147 $complexParts[4] = 1;
148 if ($complexParts[8] === '-') {
149 $complexParts[4] = -1;
150 }
151 } else {
152 // ... or if we have only the real and no imaginary part
153 // (in which case our real should be the imaginary)
154 $complexParts[4] = $complexParts[1];
155 $complexParts[1] = 0;
156 }
157 }
158
159 // Return real and imaginary parts and suffix as an array, and set a default suffix if user input lazily
160 return [
161 $complexParts[1],
162 $complexParts[4],
163 !empty($complexParts[9]) ? $complexParts[9] : 'i'
164 ];
165 }
166
167
168 public function __construct($realPart = 0.0, $imaginaryPart = null, $suffix = 'i')
169 {
170 if ($imaginaryPart === null) {
171 if (is_array($realPart)) {
172 // We have an array of (potentially) real and imaginary parts, and any suffix
173 list ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + [0.0, 0.0, 'i'];
174 } elseif ((is_string($realPart)) || (is_numeric($realPart))) {
175 // We've been given a string to parse to extract the real and imaginary parts, and any suffix
176 list($realPart, $imaginaryPart, $suffix) = self::parseComplex($realPart);
177 }
178 }
179
180 if ($imaginaryPart != 0.0 && empty($suffix)) {
181 $suffix = 'i';
182 } elseif ($imaginaryPart == 0.0 && !empty($suffix)) {
183 $suffix = '';
184 }
185
186 // Set parsed values in our properties
187 $this->realPart = (float) $realPart;
188 $this->imaginaryPart = (float) $imaginaryPart;
189 $this->suffix = strtolower($suffix ?? '');
190 }
191
192 /**
193 * Gets the real part of this complex number
194 *
195 * @return Float
196 */
197 public function getReal(): float
198 {
199 return $this->realPart;
200 }
201
202 /**
203 * Gets the imaginary part of this complex number
204 *
205 * @return Float
206 */
207 public function getImaginary(): float
208 {
209 return $this->imaginaryPart;
210 }
211
212 /**
213 * Gets the suffix of this complex number
214 *
215 * @return String
216 */
217 public function getSuffix(): string
218 {
219 return $this->suffix;
220 }
221
222 /**
223 * Returns true if this is a real value, false if a complex value
224 *
225 * @return Bool
226 */
227 public function isReal(): bool
228 {
229 return $this->imaginaryPart == 0.0;
230 }
231
232 /**
233 * Returns true if this is a complex value, false if a real value
234 *
235 * @return Bool
236 */
237 public function isComplex(): bool
238 {
239 return !$this->isReal();
240 }
241
242 public function format(): string
243 {
244 $str = "";
245 if ($this->imaginaryPart != 0.0) {
246 if (\abs($this->imaginaryPart) != 1.0) {
247 $str .= $this->imaginaryPart . $this->suffix;
248 } else {
249 $str .= (($this->imaginaryPart < 0.0) ? '-' : '') . $this->suffix;
250 }
251 }
252 if ($this->realPart != 0.0) {
253 if (($str) && ($this->imaginaryPart > 0.0)) {
254 $str = "+" . $str;
255 }
256 $str = $this->realPart . $str;
257 }
258 if (!$str) {
259 $str = "0.0";
260 }
261
262 return $str;
263 }
264
265 public function __toString(): string
266 {
267 return $this->format();
268 }
269
270 /**
271 * Validates whether the argument is a valid complex number, converting scalar or array values if possible
272 *
273 * @param mixed $complex The value to validate
274 * @return TablePress\Complex
275 * @throws Exception If the argument isn't a TablePress\Complex number or cannot be converted to one
276 */
277 public static function validateComplexArgument($complex): TablePress\Complex
278 {
279 if (is_scalar($complex) || is_array($complex)) {
280 $complex = new Complex($complex);
281 } elseif (!is_object($complex) || !($complex instanceof Complex)) {
282 throw new Exception('Value is not a valid complex number');
283 }
284
285 return $complex;
286 }
287
288 /**
289 * Returns the reverse of this complex number
290 *
291 * @return TablePress\Complex
292 */
293 public function reverse(): TablePress\Complex
294 {
295 return new Complex(
296 $this->imaginaryPart,
297 $this->realPart,
298 ($this->realPart == 0.0) ? null : $this->suffix
299 );
300 }
301
302 public function invertImaginary(): TablePress\Complex
303 {
304 return new Complex(
305 $this->realPart,
306 $this->imaginaryPart * -1,
307 ($this->imaginaryPart == 0.0) ? null : $this->suffix
308 );
309 }
310
311 public function invertReal(): TablePress\Complex
312 {
313 return new Complex(
314 $this->realPart * -1,
315 $this->imaginaryPart,
316 ($this->imaginaryPart == 0.0) ? null : $this->suffix
317 );
318 }
319
320 protected static $functions = [
321 'abs',
322 'acos',
323 'acosh',
324 'acot',
325 'acoth',
326 'acsc',
327 'acsch',
328 'argument',
329 'asec',
330 'asech',
331 'asin',
332 'asinh',
333 'atan',
334 'atanh',
335 'conjugate',
336 'cos',
337 'cosh',
338 'cot',
339 'coth',
340 'csc',
341 'csch',
342 'exp',
343 'inverse',
344 'ln',
345 'log2',
346 'log10',
347 'negative',
348 'pow',
349 'rho',
350 'sec',
351 'sech',
352 'sin',
353 'sinh',
354 'sqrt',
355 'tan',
356 'tanh',
357 'theta',
358 ];
359
360 protected static $operations = [
361 'add',
362 'subtract',
363 'multiply',
364 'divideby',
365 'divideinto',
366 ];
367
368 /**
369 * Returns the result of the function call or operation
370 *
371 * @return TablePress\Complex|float
372 * @throws Exception|\InvalidArgumentException
373 */
374 public function __call($functionName, $arguments)
375 {
376 $functionName = strtolower(str_replace('_', '', $functionName));
377
378 // Test for function calls
379 if (in_array($functionName, self::$functions, true)) {
380 return Functions::$functionName($this, ...$arguments);
381 }
382 // Test for operation calls
383 if (in_array($functionName, self::$operations, true)) {
384 return Operations::$functionName($this, ...$arguments);
385 }
386 throw new Exception('TablePress\Complex Function or Operation does not exist');
387 }
388 }
389