Home Reference Source

src/math/core/Complex.js

  1. /**
  2. * The script is part of konpeito.
  3. *
  4. * AUTHOR:
  5. * natade (http://twitter.com/natadea)
  6. *
  7. * LICENSE:
  8. * The MIT license https://opensource.org/licenses/MIT
  9. */
  10.  
  11. import Polyfill from "../tools/Polyfill.js";
  12. import Probability from "./tools/Probability.js";
  13. import Random from "./tools/Random.js";
  14. import Matrix from "./Matrix.js";
  15. import BigInteger from "./BigInteger.js";
  16. import BigDecimal from "./BigDecimal.js";
  17. import Fraction from "./Fraction.js";
  18. import MathContext from "./context/MathContext.js";
  19. import KonpeitoFloat from "./base/KonpeitoFloat.js";
  20.  
  21. /**
  22. * Complex type argument.
  23. * - Complex
  24. * - number
  25. * - boolean
  26. * - string
  27. * - Array<number>
  28. * - {_re:number,_im:number}
  29. * - {doubleValue:number}
  30. * - {toString:function}
  31. *
  32. * Initialization can be performed as follows.
  33. * - 1200, "1200", "12e2", "1.2e3"
  34. * - "3 + 4i", "4j + 3", [3, 4].
  35. * @typedef {Complex|number|boolean|string|Array<number>|{_re:number,_im:number}|{doubleValue:number}|{toString:function}} KComplexInputData
  36. */
  37.  
  38. /**
  39. * Random number generation class used within Complex.
  40. * @type {Random}
  41. * @ignore
  42. */
  43. const random_class = new Random();
  44.  
  45. /**
  46. * Collection of functions used in Complex.
  47. * @ignore
  48. */
  49. class ComplexTool {
  50.  
  51. /**
  52. * Create data for complex numbers from strings.
  53. * @param {string} text - Target strings.
  54. * @returns {{real : number, imag : number}}
  55. */
  56. static ToComplexFromString(text) {
  57. let str = text.replace(/\s/g, "").toLowerCase();
  58. str = str.replace(/infinity|inf/g, "1e100000");
  59. // 複素数の宣言がない場合
  60. if(!(/[ij]/.test(str))) {
  61. return {
  62. real : parseFloat(str),
  63. imag : 0.0
  64. };
  65. }
  66. // この時点で複素数である。
  67. // 以下真面目に調査
  68. let re = 0;
  69. let im = 0;
  70. let buff;
  71. // 最後が$なら右側が実数、最後が[+-]なら左側が実数
  72. buff = str.match(/[+-]?(([0-9]+(\.[0-9]+)?(e[+-]?[0-9]+)?)|(nan))($|[+-])/);
  73. if(buff) {
  74. re = parseFloat(buff[0]);
  75. }
  76. // 複素数は数値が省略される場合がある
  77. buff = str.match(/[+-]?(([0-9]+(\.[0-9]+)?(e[+-]?[0-9]+)?)|(nan))?[ij]/);
  78. if(buff) {
  79. buff = buff[0].substring(0, buff[0].length - 1);
  80. // i, +i, -j のように実数部がなく、数値もない場合
  81. if((/^[-+]$/.test(buff)) || buff.length === 0) {
  82. im = buff === "-" ? -1 : 1;
  83. }
  84. else {
  85. im = parseFloat(buff);
  86. }
  87. }
  88. return {
  89. real : re,
  90. imag : im
  91. };
  92. }
  93.  
  94. }
  95.  
  96. /**
  97. * Complex number class. (immutable)
  98. */
  99. export default class Complex extends KonpeitoFloat {
  100.  
  101. /**
  102. * Create a complex number.
  103. *
  104. * Initialization can be performed as follows.
  105. * - 1200, "1200", "12e2", "1.2e3"
  106. * - "3 + 4i", "4j + 3", [3, 4].
  107. * @param {KComplexInputData} number - Complex number. See how to use the function.
  108. */
  109. constructor(number) {
  110. super();
  111. // 行列で使うためイミュータブルは必ず守ること。
  112. if(arguments.length === 1) {
  113. const obj = number;
  114. if(obj instanceof Complex) {
  115. /**
  116. * The real part of this Comlex.
  117. * @private
  118. * @type {number}
  119. */
  120. this._re = obj._re;
  121. /**
  122. * The imaginary part of this Comlex.
  123. * @private
  124. * @type {number}
  125. */
  126. this._im = obj._im;
  127. }
  128. else if(typeof obj === "number") {
  129. this._re = obj;
  130. this._im = 0.0;
  131. }
  132. else if(typeof obj === "string") {
  133. const x = ComplexTool.ToComplexFromString(obj);
  134. this._re = x.real;
  135. this._im = x.imag;
  136. }
  137. else if(obj instanceof Array) {
  138. if(obj.length === 2) {
  139. this._re = obj[0];
  140. this._im = obj[1];
  141. }
  142. else {
  143. throw "Complex Unsupported argument " + arguments;
  144. }
  145. }
  146. else if(typeof obj === "boolean") {
  147. this._re = obj ? 1 : 0;
  148. this._im = 0.0;
  149. }
  150. else if("doubleValue" in obj) {
  151. this._re = obj.doubleValue;
  152. this._im = 0.0;
  153. }
  154. else if(("_re" in obj) && ("_im" in obj)) {
  155. this._re = obj._re;
  156. this._im = obj._im;
  157. }
  158. else if(obj instanceof Object) {
  159. const x = ComplexTool.ToComplexFromString(obj.toString());
  160. this._re = x.real;
  161. this._im = x.imag;
  162. }
  163. else {
  164. throw "Complex Unsupported argument " + arguments;
  165. }
  166. }
  167. else {
  168. throw "Complex Many arguments : " + arguments.length;
  169. }
  170. }
  171.  
  172. /**
  173. * Create an entity object of this class.
  174. * @param {KComplexInputData} number
  175. * @returns {Complex}
  176. */
  177. static create(number) {
  178. if(number instanceof Complex) {
  179. return number;
  180. }
  181. else {
  182. return new Complex(number);
  183. }
  184. }
  185. /**
  186. * Convert number to Complex type.
  187. * @param {KComplexInputData} number
  188. * @returns {Complex}
  189. */
  190. static valueOf(number) {
  191. return Complex.create(number);
  192. }
  193. /**
  194. * Convert to Complex.
  195. * If type conversion is unnecessary, return the value as it is.
  196. * @param {KComplexInputData} number
  197. * @returns {Complex}
  198. * @ignore
  199. */
  200. static _toComplex(number) {
  201. if(number instanceof Complex) {
  202. return number;
  203. }
  204. else if(number instanceof Matrix) {
  205. return Matrix._toComplex(number);
  206. }
  207. else {
  208. return new Complex(number);
  209. }
  210. }
  211.  
  212. /**
  213. * Convert to real number.
  214. * @param {KComplexInputData} number
  215. * @returns {number}
  216. * @ignore
  217. */
  218. static _toDouble(number) {
  219. if(typeof number === "number") {
  220. return number;
  221. }
  222. const complex_number = Complex._toComplex(number);
  223. if(complex_number.isReal()) {
  224. return complex_number.real;
  225. }
  226. else {
  227. throw "not support complex numbers.[" + number + "]";
  228. }
  229. }
  230.  
  231. /**
  232. * Convert to integer.
  233. * @param {KComplexInputData} number
  234. * @returns {number}
  235. * @ignore
  236. */
  237. static _toInteger(number) {
  238. return Math.trunc(Complex._toDouble(number));
  239. }
  240.  
  241. /**
  242. * Deep copy.
  243. * @returns {Complex}
  244. */
  245. clone() {
  246. return this;
  247. }
  248.  
  249. /**
  250. * Convert to string.
  251. * @returns {string}
  252. */
  253. toString() {
  254. /**
  255. * @type {function(number): string }
  256. */
  257. const formatG = function(x) {
  258. let numstr = x.toPrecision(6);
  259. if(numstr.indexOf(".") !== -1) {
  260. numstr = numstr.replace(/\.?0+$/, ""); // 1.00 , 1.10
  261. numstr = numstr.replace(/\.?0+e/, "e"); // 1.0e , 1.10e
  262. }
  263. else if(/inf/i.test(numstr)) {
  264. if(x === Number.POSITIVE_INFINITY) {
  265. return "Inf";
  266. }
  267. else {
  268. return "-Inf";
  269. }
  270. }
  271. else if(/nan/i.test(numstr)) {
  272. return "NaN";
  273. }
  274. return numstr;
  275. };
  276. if(!this.isReal()) {
  277. if(this._re === 0) {
  278. return formatG(this._im) + "i";
  279. }
  280. else if((this._im >= 0) || (Number.isNaN(this._im))) {
  281. return formatG(this._re) + " + " + formatG(this._im) + "i";
  282. }
  283. else {
  284. return formatG(this._re) + " - " + formatG(-this._im) + "i";
  285. }
  286. }
  287. else {
  288. return formatG(this._re);
  289. }
  290. }
  291.  
  292. /**
  293. * Convert to JSON.
  294. * @returns {string}
  295. */
  296. toJSON() {
  297. if(!this.isReal()) {
  298. if(this._re === 0) {
  299. return this._im.toString() + "i";
  300. }
  301. else if((this._im >= 0) || (Number.isNaN(this._im))) {
  302. return this._re.toString() + "+" + this._im.toString() + "i";
  303. }
  304. else {
  305. return this._re.toString() + this._im.toString() + "i";
  306. }
  307. }
  308. else {
  309. return this._re.toString();
  310. }
  311. }
  312. /**
  313. * The real part of this Comlex.
  314. * @returns {number} real(A)
  315. */
  316. get real() {
  317. return this._re;
  318. }
  319. /**
  320. * The imaginary part of this Comlex.
  321. * @returns {number} imag(A)
  322. */
  323. get imag() {
  324. return this._im;
  325. }
  326.  
  327. /**
  328. * norm.
  329. * @returns {number} |A|
  330. */
  331. get norm() {
  332. if(this._im === 0) {
  333. return Math.abs(this._re);
  334. }
  335. else if(this._re === 0) {
  336. return Math.abs(this._im);
  337. }
  338. else {
  339. return Math.sqrt(this._re * this._re + this._im * this._im);
  340. }
  341. }
  342.  
  343. /**
  344. * The argument of this complex number.
  345. * @returns {number} arg(A)
  346. */
  347. get arg() {
  348. if(this._im === 0) {
  349. return this._re >= 0 ? 0 : Math.PI;
  350. }
  351. else if(this._re === 0) {
  352. return Math.PI * (this._im >= 0.0 ? 0.5 : -0.5);
  353. }
  354. else {
  355. return Math.atan2(this._im, this._re);
  356. }
  357. }
  358.  
  359. /**
  360. * Return number of decimal places for real and imaginary parts.
  361. * - Used to make a string.
  362. * @returns {number} Number of decimal places.
  363. */
  364. getDecimalPosition() {
  365. /**
  366. * @type {function(number): number }
  367. */
  368. const getDecimal = function(x) {
  369. if(!Number.isFinite(x)) {
  370. return 0;
  371. }
  372. let a = x;
  373. let point = 0;
  374. for(let i = 0; i < 20; i++) {
  375. if(Math.abs(a - Math.round(a)) <= Number.EPSILON) {
  376. break;
  377. }
  378. a *= 10;
  379. point++;
  380. }
  381. return point;
  382. };
  383. return Math.max( getDecimal(this.real), getDecimal(this.imag) );
  384. }
  385.  
  386. /**
  387. * The positive or negative sign of this number.
  388. * - +1 if positive, -1 if negative, 0 if 0.
  389. * @returns {Complex}
  390. */
  391. sign() {
  392. if(!this.isFinite()) {
  393. if(this.isNaN() || this._im === Infinity || this._im === -Infinity) {
  394. return Complex.NaN;
  395. }
  396. if(this._re === Infinity) {
  397. return Complex.ONE;
  398. }
  399. else {
  400. return Complex.MINUS_ONE;
  401. }
  402. }
  403. if(this._im === 0) {
  404. if(this._re === 0) {
  405. return Complex.ZERO;
  406. }
  407. else {
  408. return new Complex(this._re > 0 ? 1 : -1);
  409. }
  410. }
  411. return this.div(this.norm);
  412. }
  413. // ----------------------
  414. // 四則演算
  415. // ----------------------
  416. /**
  417. * Add.
  418. * @param {KComplexInputData} number
  419. * @returns {Complex} A + B
  420. */
  421. add(number) {
  422. const A = this;
  423. const B = new Complex(number);
  424. B._re = A._re + B._re;
  425. B._im = A._im + B._im;
  426. return B;
  427. }
  428.  
  429. /**
  430. * Subtract.
  431. * @param {KComplexInputData} number
  432. * @returns {Complex} A - B
  433. */
  434. sub(number) {
  435. const A = this;
  436. const B = new Complex(number);
  437. B._re = A._re - B._re;
  438. B._im = A._im - B._im;
  439. return B;
  440. }
  441.  
  442. /**
  443. * Multiply.
  444. * @param {KComplexInputData} number
  445. * @returns {Complex} A * B
  446. */
  447. mul(number) {
  448. const A = this;
  449. const B = new Complex(number);
  450. if((A._im === 0) && (B._im === 0)) {
  451. B._re = A._re * B._re;
  452. return B;
  453. }
  454. else if((A._re === 0) && (B._re === 0)) {
  455. B._re = - A._im * B._im;
  456. B._im = 0;
  457. return B;
  458. }
  459. else {
  460. const re = A._re * B._re - A._im * B._im;
  461. const im = A._im * B._re + A._re * B._im;
  462. B._re = re;
  463. B._im = im;
  464. return B;
  465. }
  466. }
  467. /**
  468. * Inner product/Dot product.
  469. * @param {KComplexInputData} number
  470. * @returns {Complex} A * conj(B)
  471. */
  472. dot(number) {
  473. const A = this;
  474. const B = new Complex(number);
  475. if((A._im === 0) && (B._im === 0)) {
  476. B._re = A._re * B._re;
  477. return B;
  478. }
  479. else if((A._re === 0) && (B._re === 0)) {
  480. B._re = A._im * B._im;
  481. B._im = 0;
  482. return B;
  483. }
  484. else {
  485. const re = A._re * B._re + A._im * B._im;
  486. const im = - A._im * B._re + A._re * B._im;
  487. B._re = re;
  488. B._im = im;
  489. return B;
  490. }
  491. }
  492. /**
  493. * Divide.
  494. * @param {KComplexInputData} number
  495. * @returns {Complex} A / B
  496. */
  497. div(number) {
  498. const A = this;
  499. const B = new Complex(number);
  500. if((A._im === 0) && (B._im === 0)) {
  501. B._re = A._re / B._re;
  502. return B;
  503. }
  504. else if((A._re === 0) && (B._re === 0)) {
  505. B._re = A._im / B._im;
  506. B._im = 0;
  507. return B;
  508. }
  509. else {
  510. const re = A._re * B._re + A._im * B._im;
  511. const im = A._im * B._re - A._re * B._im;
  512. const denominator = 1.0 / (B._re * B._re + B._im * B._im);
  513. B._re = re * denominator;
  514. B._im = im * denominator;
  515. return B;
  516. }
  517. }
  518.  
  519. /**
  520. * Modulo, positive remainder of division.
  521. * - Result has same sign as the Dividend.
  522. * @param {KComplexInputData} number - Divided value (real number only).
  523. * @returns {Complex} A rem B
  524. */
  525. rem(number) {
  526. const A = this;
  527. const B = new Complex(number);
  528. if((A._im !== 0) || (B._im !== 0)) {
  529. throw "calculation method is undefined.";
  530. }
  531. if(!A.isFinite() || !B.isFinite() || B.isZero()) {
  532. return Complex.NaN;
  533. }
  534. B._re = A._re - B._re * (Math.trunc(A._re / B._re));
  535. return B;
  536. }
  537.  
  538. /**
  539. * Modulo, positive remainder of division.
  540. * - Result has same sign as the Divisor.
  541. * @param {KComplexInputData} number - Divided value (real number only).
  542. * @returns {Complex} A mod B
  543. */
  544. mod(number) {
  545. const A = this;
  546. const B = new Complex(number);
  547. if((A._im !== 0) || (B._im !== 0)) {
  548. throw "calculation method is undefined.";
  549. }
  550. if(B.isZero()) {
  551. return A;
  552. }
  553. const ret = A.rem(B);
  554. if(!A.equalsState(B)) {
  555. return ret.add(B);
  556. }
  557. else {
  558. return ret;
  559. }
  560. }
  561.  
  562. /**
  563. * Inverse number of this value.
  564. * @returns {Complex} 1 / A
  565. */
  566. inv() {
  567. if(this._im === 0) {
  568. return new Complex(1.0 / this._re);
  569. }
  570. else if(this._re === 0) {
  571. return new Complex([0, - 1.0 / this._im]);
  572. }
  573. return Complex.ONE.div(this);
  574. }
  575.  
  576. // ----------------------
  577. // 他の型に変換用
  578. // ----------------------
  579. /**
  580. * boolean value.
  581. * @returns {boolean}
  582. */
  583. get booleanValue() {
  584. return !this.isZero() && !this.isNaN();
  585. }
  586.  
  587. /**
  588. * integer value.
  589. * @returns {number}
  590. */
  591. get intValue() {
  592. if(!this.isFinite()) {
  593. return this.isNaN() ? NaN : (this.isPositiveInfinity() ? Infinity : -Infinity);
  594. }
  595. const value = this._re;
  596. const delta = Math.abs(value - Math.trunc(value));
  597. if(delta < Number.EPSILON) {
  598. return Math.round(value);
  599. }
  600. else {
  601. return Math.trunc(value);
  602. }
  603. }
  604.  
  605. /**
  606. * floating point.
  607. * @returns {number}
  608. */
  609. get doubleValue() {
  610. if(!this.isFinite()) {
  611. return this.isNaN() ? NaN : (this.isPositiveInfinity() ? Infinity : -Infinity);
  612. }
  613. const value = this._re;
  614. const delta = Math.abs(value - Math.trunc(value));
  615. if(delta < Number.EPSILON) {
  616. return Math.round(value);
  617. }
  618. else {
  619. return value;
  620. }
  621. }
  622.  
  623. // ----------------------
  624. // konpeito で扱う数値型へ変換
  625. // ----------------------
  626. /**
  627. * return BigInteger.
  628. * @returns {BigInteger}
  629. */
  630. toBigInteger() {
  631. return new BigInteger(this.intValue);
  632. }
  633. /**
  634. * return BigDecimal.
  635. * @param {MathContext} [mc] - MathContext setting after calculation.
  636. * @returns {BigDecimal}
  637. */
  638. toBigDecimal(mc) {
  639. if(mc) {
  640. return new BigDecimal([this.doubleValue, mc]);
  641. }
  642. else {
  643. return new BigDecimal(this.doubleValue);
  644. }
  645. }
  646. /**
  647. * return Fraction.
  648. * @returns {Fraction}
  649. */
  650. toFraction() {
  651. return new Fraction(this.doubleValue);
  652. }
  653. /**
  654. * return Complex.
  655. * @returns {Complex}
  656. */
  657. toComplex() {
  658. return this;
  659. }
  660. /**
  661. * return Matrix.
  662. * @returns {Matrix}
  663. */
  664. toMatrix() {
  665. return new Matrix(this);
  666. }
  667.  
  668. // ----------------------
  669. // 比較
  670. // ----------------------
  671. /**
  672. * Equals.
  673. * @param {KComplexInputData} number
  674. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  675. * @returns {boolean} A === B
  676. */
  677. equals(number, tolerance) {
  678. const A = this;
  679. const B = Complex._toComplex(number);
  680. // 無限大、非数の値も含めて一度確認
  681. if(A.isNaN() || B.isNaN()) {
  682. return false;
  683. }
  684. if((A._re === B._re) && (A._im === B._im)) {
  685. return true;
  686. }
  687. // 誤差を含んだ値の比較
  688. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  689. return (Math.abs(A._re - B._re) < tolerance_) && (Math.abs(A._im - B._im) < tolerance_);
  690. }
  691.  
  692. /**
  693. * Numeric type match.
  694. * @param {KComplexInputData} number
  695. * @returns {boolean}
  696. */
  697. equalsState(number) {
  698. const A = this;
  699. const B = Complex._toComplex(number);
  700. /**
  701. * @param {Complex} num
  702. * @returns {number}
  703. */
  704. const getState = function(num) {
  705. if(num.isZero()) {
  706. return 0;
  707. }
  708. if(!num.isFinite()) {
  709. if(num.isPositiveInfinity()) {
  710. return 4;
  711. }
  712. else if(num.isNegativeInfinity()) {
  713. return 5;
  714. }
  715. else {
  716. return 3;
  717. }
  718. }
  719. return num.isPositive() ? 1 : 2;
  720. };
  721. const A_type = getState(A);
  722. const B_type = getState(B);
  723. return A_type === B_type;
  724. }
  725.  
  726. /**
  727. * Compare values.
  728. * @param {KComplexInputData} number
  729. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  730. * @returns {number} A > B ? 1 : (A === B ? 0 : -1)
  731. */
  732. compareTo(number, tolerance) {
  733. const A = this;
  734. const B = Complex._toComplex(number);
  735. if(!A.isFinite() || !B.isFinite()) {
  736. if(A.equals(B)) {
  737. return 0;
  738. }
  739. else if(
  740. A.isNaN() || B.isNaN() ||
  741. (A.real === Infinity && A.imag === -Infinity) ||
  742. (A.real === -Infinity && A.imag === Infinity) ||
  743. (B.real === Infinity && B.imag === -Infinity) ||
  744. (B.real === -Infinity && B.imag === Infinity) ) {
  745. return NaN;
  746. }
  747. else if(A.isFinite()) {
  748. return B.real + B.imag < 0 ? 1 : -1;
  749. }
  750. else if(B.isFinite()) {
  751. return A.real + A.imag > 0 ? 1 : -1;
  752. }
  753. else {
  754. return NaN;
  755. }
  756. }
  757. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  758. const a = A.real + A.imag;
  759. const b = B.real + B.imag;
  760. if((Math.abs(a - b) <= tolerance_)) {
  761. return 0;
  762. }
  763. return a > b ? 1 : -1;
  764. }
  765. /**
  766. * Maximum number.
  767. * @param {KComplexInputData} number
  768. * @returns {Complex} max([A, B])
  769. */
  770. max(number) {
  771. const x = Complex._toComplex(number);
  772. if(this.compareTo(x) >= 0) {
  773. return this;
  774. }
  775. else {
  776. return x;
  777. }
  778. }
  779.  
  780. /**
  781. * Minimum number.
  782. * @param {KComplexInputData} number
  783. * @returns {Complex} min([A, B])
  784. */
  785. min(number) {
  786. const x = Complex._toComplex(number);
  787. if(this.compareTo(x) <= 0) {
  788. return this;
  789. }
  790. else {
  791. return x;
  792. }
  793. }
  794.  
  795. /**
  796. * Clip number within range.
  797. * @param {KComplexInputData} min
  798. * @param {KComplexInputData} max
  799. * @returns {Complex} min(max(x, min), max)
  800. */
  801. clip(min, max) {
  802. const min_ = Complex._toComplex(min);
  803. const max_ = Complex._toComplex(max);
  804. const arg_check = min_.compareTo(max_);
  805. if(arg_check === 1) {
  806. throw "clip(min, max) error. (min > max)->(" + min_ + " > " + max_ + ")";
  807. }
  808. else if(arg_check === 0) {
  809. return min_;
  810. }
  811. if(this.compareTo(max_) === 1) {
  812. return max_;
  813. }
  814. else if(this.compareTo(min_) === -1) {
  815. return min_;
  816. }
  817. return this;
  818. }
  819.  
  820. // ----------------------
  821. // 丸め
  822. // ----------------------
  823. /**
  824. * Floor.
  825. * @returns {Complex} floor(A)
  826. */
  827. floor() {
  828. return new Complex([Math.floor(this._re), Math.floor(this._im)]);
  829. }
  830.  
  831. /**
  832. * Ceil.
  833. * @returns {Complex} ceil(A)
  834. */
  835. ceil() {
  836. return new Complex([Math.ceil(this._re), Math.ceil(this._im)]);
  837. }
  838. /**
  839. * Rounding to the nearest integer.
  840. * @returns {Complex} round(A)
  841. */
  842. round() {
  843. return new Complex([Math.round(this._re), Math.round(this._im)]);
  844. }
  845.  
  846. /**
  847. * To integer rounded down to the nearest.
  848. * @returns {Complex} fix(A), trunc(A)
  849. */
  850. fix() {
  851. return new Complex([Math.trunc(this._re), Math.trunc(this._im)]);
  852. }
  853.  
  854. /**
  855. * Fraction.
  856. * @returns {Complex} fract(A)
  857. */
  858. fract() {
  859. return new Complex([this._re - Math.floor(this._re), this._im - Math.floor(this._im)]);
  860. }
  861.  
  862. // ----------------------
  863. // 複素数
  864. // ----------------------
  865. /**
  866. * Absolute value.
  867. * @returns {Complex} abs(A)
  868. */
  869. abs() {
  870. return new Complex(this.norm);
  871. }
  872.  
  873. /**
  874. * Complex conjugate.
  875. * @returns {Complex} real(A) - imag(A)j
  876. */
  877. conj() {
  878. if(this._im === 0) {
  879. return this;
  880. }
  881. // 共役複素数
  882. return new Complex([this._re, -this._im]);
  883. }
  884.  
  885. /**
  886. * this * -1
  887. * @returns {Complex} -A
  888. */
  889. negate() {
  890. return new Complex([-this._re, -this._im]);
  891. }
  892.  
  893. // ----------------------
  894. // 指数
  895. // ----------------------
  896. /**
  897. * Power function.
  898. * @param {KComplexInputData} number
  899. * @returns {Complex} pow(A, B)
  900. */
  901. pow(number) {
  902. const A = this;
  903. const B = new Complex(number);
  904. // -2 ^ 0.5 ... 複素数
  905. // -2 ^ 1 ... 実数
  906. // 2 ^ 0.5 ... 実数
  907. if(B.isReal()) {
  908. if(A.isReal() && (A.isNotNegative() || B.isInteger())) {
  909. B._re = Math.pow(A._re, B._re);
  910. return B;
  911. }
  912. else {
  913. const r = Math.pow(A.norm, B._re);
  914. const s = A.arg * B._re;
  915. B._re = r * Math.cos(s);
  916. B._im = r * Math.sin(s);
  917. return B;
  918. }
  919. }
  920. else {
  921. return B.mul(A.log()).exp();
  922. }
  923. }
  924.  
  925. /**
  926. * Square.
  927. * @returns {Complex} pow(A, 2)
  928. */
  929. square() {
  930. if(this._im === 0.0) {
  931. return new Complex(this._re * this._re);
  932. }
  933. return this.mul(this);
  934. }
  935.  
  936. /**
  937. * Square root.
  938. * @returns {Complex} sqrt(A)
  939. */
  940. sqrt() {
  941. if(this.isReal()) {
  942. if(this.isNotNegative()) {
  943. return new Complex(Math.sqrt(this._re));
  944. }
  945. else {
  946. return new Complex([0, Math.sqrt(-this._re)]);
  947. }
  948. }
  949. const r = Math.sqrt(this.norm);
  950. const s = this.arg * 0.5;
  951. return new Complex([r * Math.cos(s), r * Math.sin(s)]);
  952. }
  953.  
  954. /**
  955. * Cube root.
  956. * @param {KComplexInputData} [n=0] - Value type(0,1,2)
  957. * @returns {Complex} cbrt(A)
  958. */
  959. cbrt(n) {
  960. const type = Complex._toInteger(n !== undefined ? n : 0);
  961. const x = this.log().div(3).exp();
  962. if(type === 0) {
  963. return x;
  964. }
  965. else if(type === 1) {
  966. return x.mul([-0.5, Math.sqrt(3) * 0.5]);
  967. }
  968. else {
  969. return x.mul([-0.5, - Math.sqrt(3) * 0.5]);
  970. }
  971. }
  972.  
  973. /**
  974. * Reciprocal square root.
  975. * @returns {Complex} rsqrt(A)
  976. */
  977. rsqrt() {
  978. if(this.isReal()) {
  979. if(this.isNotNegative()) {
  980. return new Complex(1.0 / Math.sqrt(this._re));
  981. }
  982. else {
  983. return new Complex([0, - 1.0 / Math.sqrt(-this._re)]);
  984. }
  985. }
  986. return this.sqrt().inv();
  987. }
  988.  
  989. /**
  990. * Logarithmic function.
  991. * @returns {Complex} log(A)
  992. */
  993. log() {
  994. if(this.isReal() && this.isNotNegative()) {
  995. return new Complex(Math.log(this._re));
  996. }
  997. // 負の値が入っているか、もともと複素数が入っている場合は、複素対数関数
  998. return new Complex([Math.log(this.norm), this.arg]);
  999. }
  1000.  
  1001. /**
  1002. * Exponential function.
  1003. * @returns {Complex} exp(A)
  1004. */
  1005. exp() {
  1006. if(this.isReal()) {
  1007. return new Complex(Math.exp(this._re));
  1008. }
  1009. // 複素指数関数
  1010. const r = Math.exp(this._re);
  1011. return new Complex([r * Math.cos(this._im), r * Math.sin(this._im)]);
  1012. }
  1013.  
  1014. /**
  1015. * e^x - 1
  1016. * @returns {Complex} expm1(A)
  1017. */
  1018. expm1() {
  1019. return this.exp().sub(1);
  1020. }
  1021.  
  1022. /**
  1023. * ln(1 + x)
  1024. * @returns {Complex} log1p(A)
  1025. */
  1026. log1p() {
  1027. return this.add(1).log();
  1028. }
  1029. /**
  1030. * log_2(x)
  1031. * @returns {Complex} log2(A)
  1032. */
  1033. log2() {
  1034. return this.log().div(Complex.LN2);
  1035. }
  1036.  
  1037. /**
  1038. * log_10(x)
  1039. * @returns {Complex} log10(A)
  1040. */
  1041. log10() {
  1042. return this.log().div(Complex.LN10);
  1043. }
  1044.  
  1045. // ----------------------
  1046. // 三角関数
  1047. // ----------------------
  1048. /**
  1049. * Sine function.
  1050. * @returns {Complex} sin(A)
  1051. */
  1052. sin() {
  1053. if(this.isReal()) {
  1054. return new Complex(Math.sin(this._re));
  1055. }
  1056. // オイラーの公式より
  1057. // sin x = (e^ix - e^-ex) / 2i
  1058. const a = this.mul(Complex.I).exp();
  1059. const b = this.mul(Complex.I.negate()).exp();
  1060. return a.sub(b).div([0, 2]);
  1061. }
  1062.  
  1063. /**
  1064. * Cosine function.
  1065. * @returns {Complex} cos(A)
  1066. */
  1067. cos() {
  1068. if(this.isReal()) {
  1069. return new Complex(Math.cos(this._re));
  1070. }
  1071. // オイラーの公式より
  1072. // cos x = (e^ix + e^-ex) / 2
  1073. const a = this.mul(Complex.I).exp();
  1074. const b = this.mul(Complex.I.negate()).exp();
  1075. return a.add(b).div(2);
  1076. }
  1077.  
  1078. /**
  1079. * Tangent function.
  1080. * @returns {Complex} tan(A)
  1081. */
  1082. tan() {
  1083. if(this.isReal()) {
  1084. return new Complex(Math.tan(this._re));
  1085. }
  1086. // 三角関数の相互関係 tan x = sin x / cos x
  1087. return this.sin().div(this.cos());
  1088. }
  1089.  
  1090. /**
  1091. * Atan (arc tangent) function.
  1092. * - Return the values of [-PI/2, PI/2].
  1093. * @returns {Complex} atan(A)
  1094. */
  1095. atan() {
  1096. if(this.isReal()) {
  1097. return new Complex(Math.atan(this._re));
  1098. }
  1099. // 逆正接 tan-1 x = i/2 log( i+x / i-x )
  1100. return Complex.I.div(Complex.TWO).mul(Complex.I.add(this).div(Complex.I.sub(this)).log());
  1101. }
  1102.  
  1103. /**
  1104. * Atan (arc tangent) function.
  1105. * Return the values of [-PI, PI] .
  1106. * Supports only real numbers.
  1107. * @param {KComplexInputData} [number] - X
  1108. * @returns {Complex} atan2(Y, X)
  1109. */
  1110. atan2(number) {
  1111. if(arguments.length === 0) {
  1112. return new Complex(this.arg);
  1113. }
  1114. // y.atan2(x) とする。
  1115. const y = this;
  1116. const x = Complex._toComplex(number);
  1117. if(y.isReal() && x.isReal()) {
  1118. return new Complex(Math.atan2(y._re, x._re));
  1119. }
  1120. // 複素数のatan2は未定義である(実装不可能)
  1121. throw "calculation method is undefined.";
  1122. }
  1123. // ----------------------
  1124. // 双曲線関数
  1125. // ----------------------
  1126. /**
  1127. * Arc sine function.
  1128. * @returns {Complex} asin(A)
  1129. */
  1130. asin() {
  1131. // 逆正弦
  1132. return this.mul(Complex.I).add(Complex.ONE.sub(this.square()).sqrt()).log().mul(Complex.MINUS_I);
  1133. }
  1134.  
  1135. /**
  1136. * Arc cosine function.
  1137. * @returns {Complex} acos(A)
  1138. */
  1139. acos() {
  1140. // 逆余弦
  1141. return this.add(Complex.I.mul(Complex.ONE.sub(this.square()).sqrt())).log().mul(Complex.MINUS_I);
  1142. }
  1143.  
  1144. /**
  1145. * Hyperbolic sine function.
  1146. * @returns {Complex} sinh(A)
  1147. */
  1148. sinh() {
  1149. // 双曲線正弦
  1150. const y = this.exp();
  1151. return y.sub(y.inv()).mul(0.5);
  1152. }
  1153.  
  1154. /**
  1155. * Inverse hyperbolic sine function.
  1156. * @returns {Complex} asinh(A)
  1157. */
  1158. asinh() {
  1159. // 逆双曲線正弦 Math.log(x + Math.sqrt(x * x + 1));
  1160. if(this.isInfinite()) {
  1161. return this;
  1162. }
  1163. return this.add(this.mul(this).add(1).sqrt()).log();
  1164. }
  1165.  
  1166. /**
  1167. * Hyperbolic cosine function.
  1168. * @returns {Complex} cosh(A)
  1169. */
  1170. cosh() {
  1171. // 双曲線余弦
  1172. return this.exp().add(this.negate().exp()).mul(0.5);
  1173. }
  1174.  
  1175. /**
  1176. * Inverse hyperbolic cosine function.
  1177. * @returns {Complex} acosh(A)
  1178. */
  1179. acosh() {
  1180. // 逆双曲線余弦 Math.log(x + Math.sqrt(x * x - 1));
  1181. // Octave だと log(0.5+(0.5*0.5-1)^0.5) !== acosh(0.5) になる。
  1182. // おそらく log(0.5-(0.5*0.5-1)^0.5) の式に切り替わるようになっている
  1183. // これは2つの値を持っているためだと思われるので合わせてみる
  1184. if(this.isZero()) {
  1185. return new Complex([0, Math.PI * 0.5]);
  1186. }
  1187. if(this.compareTo(Complex.ONE) >= 1) {
  1188. return this.add(this.square().sub(1).sqrt()).log();
  1189. }
  1190. else {
  1191. return this.sub(this.square().sub(1).sqrt()).log();
  1192. }
  1193. }
  1194.  
  1195. /**
  1196. * Hyperbolic tangent function.
  1197. * @returns {Complex} tanh(A)
  1198. */
  1199. tanh() {
  1200. // 双曲線正接
  1201. if(this.isNaN()) {
  1202. return Complex.NaN;
  1203. }
  1204. const y = this.mul(2).exp();
  1205. if(y.isZero()) {
  1206. return Complex.MINUS_ONE;
  1207. }
  1208. else if(y.isPositiveInfinity()) {
  1209. return Complex.ONE;
  1210. }
  1211. return y.sub(1).div(y.add(1));
  1212. }
  1213. /**
  1214. * Inverse hyperbolic tangent function.
  1215. * @returns {Complex} atanh(A)
  1216. */
  1217. atanh() {
  1218. // 逆双曲線正接
  1219. if(this.isInfinite() && this.isReal()) {
  1220. return new Complex([0, Math.PI * 0.5]);
  1221. }
  1222. return this.add(1).div(this.negate().add(1)).log().mul(0.5);
  1223. }
  1224.  
  1225. /**
  1226. * Secant function.
  1227. * @returns {Complex} sec(A)
  1228. */
  1229. sec() {
  1230. // 正割
  1231. return this.cos().inv();
  1232. }
  1233.  
  1234. /**
  1235. * Reverse secant function.
  1236. * @returns {Complex} asec(A)
  1237. */
  1238. asec() {
  1239. // 逆正割
  1240. return this.inv().acos();
  1241. }
  1242.  
  1243. /**
  1244. * Hyperbolic secant function.
  1245. * @returns {Complex} sech(A)
  1246. */
  1247. sech() {
  1248. // 双曲線正割
  1249. return this.exp().add(this.negate().exp()).inv().mul(2);
  1250. }
  1251.  
  1252. /**
  1253. * Inverse hyperbolic secant function.
  1254. * @returns {Complex} asech(A)
  1255. */
  1256. asech() {
  1257. // 逆双曲線正割
  1258. if(this.isInfinite() && this.isReal()) {
  1259. return new Complex([0, Math.PI * 0.5]);
  1260. }
  1261. if(this.isPositive() || (this.compareTo(Complex.MINUS_ONE) == -1)) {
  1262. return this.inv().add(this.square().inv().sub(1).sqrt()).log();
  1263. }
  1264. else {
  1265. return this.inv().sub(this.square().inv().sub(1).sqrt()).log();
  1266. }
  1267. }
  1268.  
  1269. /**
  1270. * Cotangent function.
  1271. * @returns {Complex} cot(A)
  1272. */
  1273. cot() {
  1274. // 余接
  1275. return this.tan().inv();
  1276. }
  1277.  
  1278. /**
  1279. * Inverse cotangent function.
  1280. * @returns {Complex} acot(A)
  1281. */
  1282. acot() {
  1283. // 逆余接
  1284. return this.inv().atan();
  1285. }
  1286.  
  1287. /**
  1288. * Hyperbolic cotangent function.
  1289. * @returns {Complex} coth(A)
  1290. */
  1291. coth() {
  1292. // 双曲線余接
  1293. if(this.isZero()) {
  1294. return Complex.POSITIVE_INFINITY;
  1295. }
  1296. return this.tanh().inv();
  1297. }
  1298.  
  1299. /**
  1300. * Inverse hyperbolic cotangent function.
  1301. * @returns {Complex} acoth(A)
  1302. */
  1303. acoth() {
  1304. // 逆双曲線余接
  1305. if(this.isInfinite()) {
  1306. return Complex.ZERO;
  1307. }
  1308. return this.add(1).div(this.sub(1)).log().mul(0.5);
  1309. }
  1310.  
  1311. /**
  1312. * Cosecant function.
  1313. * @returns {Complex} csc(A)
  1314. */
  1315. csc() {
  1316. // 余割
  1317. return this.sin().inv();
  1318. }
  1319.  
  1320. /**
  1321. * Inverse cosecant function.
  1322. * @returns {Complex} acsc(A)
  1323. */
  1324. acsc() {
  1325. // 逆余割
  1326. return this.inv().asin();
  1327. }
  1328.  
  1329. /**
  1330. * Hyperbolic cosecant function.
  1331. * @returns {Complex} csch(A)
  1332. */
  1333. csch() {
  1334. // 双曲線余割
  1335. return this.exp().sub(this.negate().exp()).inv().mul(2);
  1336. }
  1337.  
  1338. /**
  1339. * Inverse hyperbolic cosecant function.
  1340. * @returns {Complex} acsch(A)
  1341. */
  1342. acsch() {
  1343. // 逆双曲線余割
  1344. return this.inv().add(this.square().inv().add(1).sqrt()).log();
  1345. }
  1346.  
  1347. // ----------------------
  1348. // 確率・統計系
  1349. // ----------------------
  1350. /**
  1351. * Logit function.
  1352. * @returns {Complex} logit(A)
  1353. */
  1354. logit() {
  1355. return this.log().sub(Complex.ONE.sub(this).log());
  1356. }
  1357.  
  1358. // ----------------------
  1359. // 信号処理系
  1360. // ----------------------
  1361. /**
  1362. * Normalized sinc function.
  1363. * @returns {Complex} sinc(A)
  1364. */
  1365. sinc() {
  1366. if(this.isReal()) {
  1367. if(this._re === 0) {
  1368. return(Complex.ONE);
  1369. }
  1370. const x = Math.PI * this._re;
  1371. return new Complex(Math.sin(x) / x);
  1372. }
  1373. const x = this.mul(Complex.PI);
  1374. return new Complex( x.sin().div(x) );
  1375. }
  1376.  
  1377. // ----------------------
  1378. // 乱数
  1379. // ----------------------
  1380. /**
  1381. * Create random values [0, 1) with uniform random numbers.
  1382. * @param {Random} [random] - Class for creating random numbers.
  1383. * @returns {Complex}
  1384. */
  1385. static rand(random) {
  1386. const rand = (random !== undefined && random instanceof Random) ? random : random_class;
  1387. return new Complex(rand.nextDouble());
  1388. }
  1389.  
  1390. /**
  1391. * Create random values with normal distribution.
  1392. * @param {Random} [random] - Class for creating random numbers.
  1393. * @returns {Complex}
  1394. */
  1395. static randn(random) {
  1396. const rand = (random !== undefined && random instanceof Random) ? random : random_class;
  1397. return new Complex(rand.nextGaussian());
  1398. }
  1399.  
  1400. // ----------------------
  1401. // テスト系
  1402. // ----------------------
  1403. /**
  1404. * Return true if the value is integer.
  1405. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1406. * @returns {boolean}
  1407. */
  1408. isInteger(tolerance) {
  1409. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1410. return this.isReal() && (Math.abs(this._re - Math.trunc(this._re)) < tolerance_);
  1411. }
  1412.  
  1413. /**
  1414. * Returns true if the vallue is complex integer (including normal integer).
  1415. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1416. * @returns {boolean} real(A) === integer && imag(A) === integer
  1417. */
  1418. isComplexInteger(tolerance) {
  1419. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1420. // 複素整数
  1421. return (Math.abs(this._re - Math.trunc(this._re)) < tolerance_) &&
  1422. (Math.abs(this._im - Math.trunc(this._im)) < tolerance_);
  1423. }
  1424.  
  1425. /**
  1426. * this === 0
  1427. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1428. * @returns {boolean} A === 0
  1429. */
  1430. isZero(tolerance) {
  1431. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1432. return (Math.abs(this._re) < tolerance_) && (Math.abs(this._im) < tolerance_);
  1433. }
  1434.  
  1435. /**
  1436. * this === 1
  1437. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1438. * @returns {boolean} A === 1
  1439. */
  1440. isOne(tolerance) {
  1441. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1442. return (Math.abs(this._re - 1.0) < tolerance_) && (Math.abs(this._im) < tolerance_);
  1443. }
  1444.  
  1445. /**
  1446. * Returns true if the vallue is complex number (imaginary part is not 0).
  1447. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1448. * @returns {boolean} imag(A) !== 0
  1449. */
  1450. isComplex(tolerance) {
  1451. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1452. return (Math.abs(this._im) >= tolerance_);
  1453. }
  1454. /**
  1455. * Return true if the value is real number.
  1456. * @param {KComplexInputData} [tolerance=Number.EPSILON] - Calculation tolerance of calculation.
  1457. * @returns {boolean} imag(A) === 0
  1458. */
  1459. isReal(tolerance) {
  1460. const tolerance_ = tolerance ? Complex._toDouble(tolerance) : Number.EPSILON;
  1461. return (Math.abs(this._im) < tolerance_);
  1462. }
  1463.  
  1464. /**
  1465. * this === NaN
  1466. * @returns {boolean} isNaN(A)
  1467. */
  1468. isNaN() {
  1469. return isNaN(this._re) || isNaN(this._im);
  1470. }
  1471.  
  1472. /**
  1473. * Return true if this real part of the complex positive.
  1474. * @returns {boolean} real(x) > 0
  1475. */
  1476. isPositive() {
  1477. // Number.EPSILONは使用しない。どちらにぶれるか不明な点及び
  1478. // わずかな負の数だった場合に、sqrtでエラーが発生するため
  1479. return 0.0 < this._re;
  1480. }
  1481.  
  1482. /**
  1483. * real(this) < 0
  1484. * @returns {boolean} real(x) < 0
  1485. */
  1486. isNegative() {
  1487. return 0.0 > this._re;
  1488. }
  1489.  
  1490. /**
  1491. * real(this) >= 0
  1492. * @returns {boolean} real(x) >= 0
  1493. */
  1494. isNotNegative() {
  1495. return 0.0 <= this._re;
  1496. }
  1497.  
  1498. /**
  1499. * this === Infinity
  1500. * @returns {boolean} isPositiveInfinity(A)
  1501. */
  1502. isPositiveInfinity() {
  1503. return this._re === Number.POSITIVE_INFINITY || this._im === Number.POSITIVE_INFINITY;
  1504. }
  1505.  
  1506. /**
  1507. * this === -Infinity
  1508. * @returns {boolean} isNegativeInfinity(A)
  1509. */
  1510. isNegativeInfinity() {
  1511. return this._re === Number.NEGATIVE_INFINITY || this._im === Number.NEGATIVE_INFINITY;
  1512. }
  1513.  
  1514. /**
  1515. * this === Infinity or -Infinity
  1516. * @returns {boolean} isPositiveInfinity(A) || isNegativeInfinity(A)
  1517. */
  1518. isInfinite() {
  1519. return this.isPositiveInfinity() || this.isNegativeInfinity();
  1520. }
  1521. /**
  1522. * Return true if the value is finite number.
  1523. * @returns {boolean} !isNaN(A) && !isInfinite(A)
  1524. */
  1525. isFinite() {
  1526. return !this.isNaN() && !this.isInfinite();
  1527. }
  1528.  
  1529. // ----------------------
  1530. // 確率
  1531. // ----------------------
  1532. /**
  1533. * Log-gamma function.
  1534. * - Calculate from real values.
  1535. * @returns {Complex}
  1536. */
  1537. gammaln() {
  1538. return new Complex(Probability.gammaln(this._re));
  1539. }
  1540. /**
  1541. * Gamma function.
  1542. * - Calculate from real values.
  1543. * @returns {Complex}
  1544. */
  1545. gamma() {
  1546. return new Complex(Probability.gamma(this._re));
  1547. }
  1548. /**
  1549. * Incomplete gamma function.
  1550. * - Calculate from real values.
  1551. * @param {KComplexInputData} a
  1552. * @param {string} [tail="lower"] - lower (default) , "upper"
  1553. * @returns {Complex}
  1554. */
  1555. gammainc(a, tail) {
  1556. const a_ = Complex._toDouble(a);
  1557. return new Complex(Probability.gammainc(this._re, a_, tail));
  1558. }
  1559.  
  1560. /**
  1561. * Probability density function (PDF) of the gamma distribution.
  1562. * - Calculate from real values.
  1563. * @param {KComplexInputData} k - Shape parameter.
  1564. * @param {KComplexInputData} s - Scale parameter.
  1565. * @returns {Complex}
  1566. */
  1567. gampdf(k, s) {
  1568. const k_ = Complex._toDouble(k);
  1569. const s_ = Complex._toDouble(s);
  1570. return new Complex(Probability.gampdf(this._re, k_, s_));
  1571. }
  1572.  
  1573. /**
  1574. * Cumulative distribution function (CDF) of gamma distribution.
  1575. * - Calculate from real values.
  1576. * @param {KComplexInputData} k - Shape parameter.
  1577. * @param {KComplexInputData} s - Scale parameter.
  1578. * @returns {Complex}
  1579. */
  1580. gamcdf(k, s) {
  1581. const k_ = Complex._toDouble(k);
  1582. const s_ = Complex._toDouble(s);
  1583. return new Complex(Probability.gamcdf(this._re, k_, s_));
  1584. }
  1585.  
  1586. /**
  1587. * Inverse function of cumulative distribution function (CDF) of gamma distribution.
  1588. * - Calculate from real values.
  1589. * @param {KComplexInputData} k - Shape parameter.
  1590. * @param {KComplexInputData} s - Scale parameter.
  1591. * @returns {Complex}
  1592. */
  1593. gaminv(k, s) {
  1594. const k_ = Complex._toDouble(k);
  1595. const s_ = Complex._toDouble(s);
  1596. return new Complex(Probability.gaminv(this._re, k_, s_));
  1597. }
  1598.  
  1599. /**
  1600. * Beta function.
  1601. * - Calculate from real values.
  1602. * @param {KComplexInputData} y
  1603. * @returns {Complex}
  1604. */
  1605. beta(y) {
  1606. const y_ = Complex._toDouble(y);
  1607. return new Complex(Probability.beta(this._re, y_));
  1608. }
  1609.  
  1610. /**
  1611. * Incomplete beta function.
  1612. * - Calculate from real values.
  1613. * @param {KComplexInputData} a
  1614. * @param {KComplexInputData} b
  1615. * @param {string} [tail="lower"] - lower (default) , "upper"
  1616. * @returns {Complex}
  1617. */
  1618. betainc(a, b, tail) {
  1619. const a_ = Complex._toDouble(a);
  1620. const b_ = Complex._toDouble(b);
  1621. return new Complex(Probability.betainc(this._re, a_, b_, tail));
  1622. }
  1623.  
  1624. /**
  1625. * Probability density function (PDF) of beta distribution.
  1626. * - Calculate from real values.
  1627. * @param {KComplexInputData} a
  1628. * @param {KComplexInputData} b
  1629. * @returns {Complex}
  1630. */
  1631. betapdf(a, b) {
  1632. const a_ = Complex._toDouble(a);
  1633. const b_ = Complex._toDouble(b);
  1634. return new Complex(Probability.betapdf(this._re, a_, b_));
  1635. }
  1636.  
  1637. /**
  1638. * Cumulative distribution function (CDF) of beta distribution.
  1639. * - Calculate from real values.
  1640. * @param {KComplexInputData} a
  1641. * @param {KComplexInputData} b
  1642. * @returns {Complex}
  1643. */
  1644. betacdf(a, b) {
  1645. const a_ = Complex._toDouble(a);
  1646. const b_ = Complex._toDouble(b);
  1647. return new Complex(Probability.betacdf(this._re, a_, b_));
  1648. }
  1649.  
  1650. /**
  1651. * Inverse function of cumulative distribution function (CDF) of beta distribution.
  1652. * - Calculate from real values.
  1653. * @param {KComplexInputData} a
  1654. * @param {KComplexInputData} b
  1655. * @returns {Complex}
  1656. */
  1657. betainv(a, b) {
  1658. const a_ = Complex._toDouble(a);
  1659. const b_ = Complex._toDouble(b);
  1660. return new Complex(Probability.betainv(this._re, a_, b_));
  1661. }
  1662.  
  1663. /**
  1664. * Factorial function, x!.
  1665. * - Calculate from real values.
  1666. * @returns {Complex}
  1667. */
  1668. factorial() {
  1669. return new Complex(Probability.factorial(this._re));
  1670. }
  1671.  
  1672. /**
  1673. * Binomial coefficient, number of all combinations, nCk.
  1674. * - Calculate from real values.
  1675. * @param {KComplexInputData} k
  1676. * @returns {Complex}
  1677. */
  1678. nchoosek(k) {
  1679. const k_ = Complex._toDouble(k);
  1680. return new Complex(Probability.nchoosek(this._re, k_));
  1681. }
  1682. /**
  1683. * Error function.
  1684. * - Calculate from real values.
  1685. * @returns {Complex}
  1686. */
  1687. erf() {
  1688. return new Complex(Probability.erf(this._re));
  1689. }
  1690.  
  1691. /**
  1692. * Complementary error function.
  1693. * - Calculate from real values.
  1694. * @returns {Complex}
  1695. */
  1696. erfc() {
  1697. return new Complex(Probability.erfc(this._re));
  1698. }
  1699.  
  1700. /**
  1701. * Inverse function of Error function.
  1702. * - Calculate from real values.
  1703. * @returns {Complex}
  1704. */
  1705. erfinv() {
  1706. return new Complex(Probability.erfinv(this._re));
  1707. }
  1708.  
  1709. /**
  1710. * Inverse function of Complementary error function.
  1711. * - Calculate from real values.
  1712. * @returns {Complex}
  1713. */
  1714. erfcinv() {
  1715. return new Complex(Probability.erfcinv(this._re));
  1716. }
  1717.  
  1718. /**
  1719. * Probability density function (PDF) of normal distribution.
  1720. * - Calculate from real values.
  1721. * @param {KComplexInputData} [u=0.0] - Average value.
  1722. * @param {KComplexInputData} [s=1.0] - Variance value.
  1723. * @returns {Complex}
  1724. */
  1725. normpdf(u, s) {
  1726. const u_ = u !== undefined ? Complex._toDouble(u) : 0.0;
  1727. const s_ = s !== undefined ? Complex._toDouble(s) : 1.0;
  1728. return new Complex(Probability.normpdf(this._re, u_, s_));
  1729. }
  1730.  
  1731. /**
  1732. * Cumulative distribution function (CDF) of normal distribution.
  1733. * - Calculate from real values.
  1734. * @param {KComplexInputData} [u=0.0] - Average value.
  1735. * @param {KComplexInputData} [s=1.0] - Variance value.
  1736. * @returns {Complex}
  1737. */
  1738. normcdf(u, s) {
  1739. const u_ = u !== undefined ? Complex._toDouble(u) : 0.0;
  1740. const s_ = s !== undefined ? Complex._toDouble(s) : 1.0;
  1741. return new Complex(Probability.normcdf(this._re, u_, s_));
  1742. }
  1743.  
  1744. /**
  1745. * Inverse function of cumulative distribution function (CDF) of normal distribution.
  1746. * - Calculate from real values.
  1747. * @param {KComplexInputData} [u=0.0] - Average value.
  1748. * @param {KComplexInputData} [s=1.0] - Variance value.
  1749. * @returns {Complex}
  1750. */
  1751. norminv(u, s) {
  1752. const u_ = u !== undefined ? Complex._toDouble(u) : 0.0;
  1753. const s_ = s !== undefined ? Complex._toDouble(s) : 1.0;
  1754. return new Complex(Probability.norminv(this._re, u_, s_));
  1755. }
  1756. /**
  1757. * Probability density function (PDF) of binomial distribution.
  1758. * - Calculate from real values.
  1759. * @param {KComplexInputData} n
  1760. * @param {KComplexInputData} p
  1761. * @returns {Complex}
  1762. */
  1763. binopdf(n, p) {
  1764. const n_ = Complex._toDouble(n);
  1765. const p_ = Complex._toDouble(p);
  1766. return new Complex(Probability.binopdf(this._re, n_, p_));
  1767. }
  1768.  
  1769. /**
  1770. * Cumulative distribution function (CDF) of binomial distribution.
  1771. * - Calculate from real values.
  1772. * @param {KComplexInputData} n
  1773. * @param {KComplexInputData} p
  1774. * @param {string} [tail="lower"] - lower (default) , "upper"
  1775. * @returns {Complex}
  1776. */
  1777. binocdf(n, p, tail) {
  1778. const n_ = Complex._toDouble(n);
  1779. const p_ = Complex._toDouble(p);
  1780. return new Complex(Probability.binocdf(this._re, n_, p_, tail));
  1781. }
  1782.  
  1783. /**
  1784. * Inverse function of cumulative distribution function (CDF) of binomial distribution.
  1785. * - Calculate from real values.
  1786. * @param {KComplexInputData} n
  1787. * @param {KComplexInputData} p
  1788. * @returns {Complex}
  1789. */
  1790. binoinv(n, p) {
  1791. const n_ = Complex._toDouble(n);
  1792. const p_ = Complex._toDouble(p);
  1793. return new Complex(Probability.binoinv(this._re, n_, p_));
  1794. }
  1795.  
  1796. /**
  1797. * Probability density function (PDF) of Poisson distribution.
  1798. * - Calculate from real values.
  1799. * @param {KComplexInputData} lambda
  1800. * @returns {Complex}
  1801. */
  1802. poisspdf(lambda) {
  1803. const lambda_ = Complex._toDouble(lambda);
  1804. return new Complex(Probability.poisspdf(this._re, lambda_));
  1805. }
  1806.  
  1807. /**
  1808. * Cumulative distribution function (CDF) of Poisson distribution.
  1809. * - Calculate from real values.
  1810. * @param {KComplexInputData} lambda
  1811. * @returns {Complex}
  1812. */
  1813. poisscdf(lambda) {
  1814. const lambda_ = Complex._toDouble(lambda);
  1815. return new Complex(Probability.poisscdf(this._re, lambda_));
  1816. }
  1817.  
  1818. /**
  1819. * Inverse function of cumulative distribution function (CDF) of Poisson distribution.
  1820. * - Calculate from real values.
  1821. * @param {KComplexInputData} lambda
  1822. * @returns {Complex}
  1823. */
  1824. poissinv(lambda) {
  1825. const lambda_ = Complex._toDouble(lambda);
  1826. return new Complex(Probability.poissinv(this._re, lambda_));
  1827. }
  1828.  
  1829. /**
  1830. * Probability density function (PDF) of Student's t-distribution.
  1831. * - Calculate from real values.
  1832. * @param {KComplexInputData} v - The degrees of freedom. (DF)
  1833. * @returns {Complex}
  1834. */
  1835. tpdf(v) {
  1836. const v_ = Complex._toDouble(v);
  1837. return new Complex(Probability.tpdf(this._re, v_));
  1838. }
  1839.  
  1840. /**
  1841. * Cumulative distribution function (CDF) of Student's t-distribution.
  1842. * - Calculate from real values.
  1843. * @param {KComplexInputData} v - The degrees of freedom. (DF)
  1844. * @returns {Complex}
  1845. */
  1846. tcdf(v) {
  1847. const v_ = Complex._toDouble(v);
  1848. return new Complex(Probability.tcdf(this._re, v_));
  1849. }
  1850.  
  1851. /**
  1852. * Inverse of cumulative distribution function (CDF) of Student's t-distribution.
  1853. * - Calculate from real values.
  1854. * @param {KComplexInputData} v - The degrees of freedom. (DF)
  1855. * @returns {Complex}
  1856. */
  1857. tinv(v) {
  1858. const v_ = Complex._toDouble(v);
  1859. return new Complex(Probability.tinv(this._re, v_));
  1860. }
  1861.  
  1862. /**
  1863. * Cumulative distribution function (CDF) of Student's t-distribution that can specify tail.
  1864. * - Calculate from real values.
  1865. * @param {KComplexInputData} v - The degrees of freedom. (DF)
  1866. * @param {KComplexInputData} tails - Tail. (1 = the one-tailed distribution, 2 = the two-tailed distribution.)
  1867. * @returns {Complex}
  1868. */
  1869. tdist(v, tails) {
  1870. const v_ = Complex._toDouble(v);
  1871. const tails_ = Complex._toInteger(tails);
  1872. return new Complex(Probability.tdist(this._re, v_, tails_));
  1873. }
  1874.  
  1875. /**
  1876. * Inverse of cumulative distribution function (CDF) of Student's t-distribution in two-sided test.
  1877. * - Calculate from real values.
  1878. * @param {KComplexInputData} v - The degrees of freedom. (DF)
  1879. * @returns {Complex}
  1880. */
  1881. tinv2(v) {
  1882. const v_ = Complex._toDouble(v);
  1883. return new Complex(Probability.tinv2(this._re, v_));
  1884. }
  1885.  
  1886. /**
  1887. * Probability density function (PDF) of chi-square distribution.
  1888. * - Calculate from real values.
  1889. * @param {KComplexInputData} k - The degrees of freedom. (DF)
  1890. * @returns {Complex}
  1891. */
  1892. chi2pdf(k) {
  1893. const k_ = Complex._toDouble(k);
  1894. return new Complex(Probability.chi2pdf(this._re, k_));
  1895. }
  1896.  
  1897. /**
  1898. * Cumulative distribution function (CDF) of chi-square distribution.
  1899. * - Calculate from real values.
  1900. * @param {KComplexInputData} k - The degrees of freedom. (DF)
  1901. * @returns {Complex}
  1902. */
  1903. chi2cdf(k) {
  1904. const k_ = Complex._toDouble(k);
  1905. return new Complex(Probability.chi2cdf(this._re, k_));
  1906. }
  1907.  
  1908. /**
  1909. * Inverse function of cumulative distribution function (CDF) of chi-square distribution.
  1910. * - Calculate from real values.
  1911. * @param {KComplexInputData} k - The degrees of freedom. (DF)
  1912. * @returns {Complex}
  1913. */
  1914. chi2inv(k) {
  1915. const k_ = Complex._toDouble(k);
  1916. return new Complex(Probability.chi2inv(this._re, k_));
  1917. }
  1918.  
  1919. /**
  1920. * Probability density function (PDF) of F-distribution.
  1921. * - Calculate from real values.
  1922. * @param {KComplexInputData} d1 - The degree of freedom of the molecules.
  1923. * @param {KComplexInputData} d2 - The degree of freedom of the denominator
  1924. * @returns {Complex}
  1925. */
  1926. fpdf(d1, d2) {
  1927. const d1_ = Complex._toDouble(d1);
  1928. const d2_ = Complex._toDouble(d2);
  1929. return new Complex(Probability.fpdf(this._re, d1_, d2_));
  1930. }
  1931.  
  1932. /**
  1933. * Cumulative distribution function (CDF) of F-distribution.
  1934. * - Calculate from real values.
  1935. * @param {KComplexInputData} d1 - The degree of freedom of the molecules.
  1936. * @param {KComplexInputData} d2 - The degree of freedom of the denominator
  1937. * @returns {Complex}
  1938. */
  1939. fcdf(d1, d2) {
  1940. const d1_ = Complex._toDouble(d1);
  1941. const d2_ = Complex._toDouble(d2);
  1942. return new Complex(Probability.fcdf(this._re, d1_, d2_));
  1943. }
  1944.  
  1945. /**
  1946. * Inverse function of cumulative distribution function (CDF) of F-distribution.
  1947. * - Calculate from real values.
  1948. * @param {KComplexInputData} d1 - The degree of freedom of the molecules.
  1949. * @param {KComplexInputData} d2 - The degree of freedom of the denominator
  1950. * @returns {Complex}
  1951. */
  1952. finv(d1, d2) {
  1953. const d1_ = Complex._toDouble(d1);
  1954. const d2_ = Complex._toDouble(d2);
  1955. return new Complex(Probability.finv(this._re, d1_, d2_));
  1956. }
  1957.  
  1958. // ----------------------
  1959. // ビット演算系
  1960. // ----------------------
  1961. /**
  1962. * Logical AND.
  1963. * - Calculated as an integer.
  1964. * @param {KComplexInputData} number
  1965. * @returns {Complex} A & B
  1966. */
  1967. and(number) {
  1968. const n_src = Math.round(this.real);
  1969. const n_tgt = Math.round(Complex._toDouble(number));
  1970. return new Complex(n_src & n_tgt);
  1971. }
  1972.  
  1973. /**
  1974. * Logical OR.
  1975. * - Calculated as an integer.
  1976. * @param {KComplexInputData} number
  1977. * @returns {Complex} A | B
  1978. */
  1979. or(number) {
  1980. const n_src = Math.round(this.real);
  1981. const n_tgt = Math.round(Complex._toDouble(number));
  1982. return new Complex(n_src | n_tgt);
  1983. }
  1984.  
  1985. /**
  1986. * Logical Exclusive-OR.
  1987. * - Calculated as an integer.
  1988. * @param {KComplexInputData} number
  1989. * @returns {Complex} A ^ B
  1990. */
  1991. xor(number) {
  1992. const n_src = Math.round(this.real);
  1993. const n_tgt = Math.round(Complex._toDouble(number));
  1994. return new Complex(n_src ^ n_tgt);
  1995. }
  1996.  
  1997. /**
  1998. * Logical Not. (mutable)
  1999. * - Calculated as an integer.
  2000. * @returns {Complex} !A
  2001. */
  2002. not() {
  2003. const n_src = Math.round(this.real);
  2004. return new Complex(!n_src);
  2005. }
  2006. /**
  2007. * this << n
  2008. * - Calculated as an integer.
  2009. * @param {KComplexInputData} n
  2010. * @returns {Complex} A << n
  2011. */
  2012. shift(n) {
  2013. const src = Math.round(this.real);
  2014. const number = Math.round(Complex._toDouble(n));
  2015. return new Complex(src << number);
  2016. }
  2017.  
  2018. // ----------------------
  2019. // factor
  2020. // ----------------------
  2021.  
  2022. /**
  2023. * Factorization.
  2024. * - Calculated as an integer.
  2025. * - Calculate up to `9007199254740991`.
  2026. * @returns {Complex[]} factor
  2027. */
  2028. factor() {
  2029. const x = this.round().toBigInteger().factor();
  2030. const y = [];
  2031. for(let i = 0; i < x.length; i++) {
  2032. y.push(new Complex(x[i]));
  2033. }
  2034. return y;
  2035. }
  2036.  
  2037. // ----------------------
  2038. // gcd, lcm
  2039. // ----------------------
  2040. /**
  2041. * Euclidean algorithm.
  2042. * - Calculated as an integer.
  2043. * @param {KComplexInputData} number
  2044. * @returns {Complex} gcd(x, y)
  2045. */
  2046. gcd(number) {
  2047. const x = Math.round(this.real);
  2048. const y = Math.round(Complex._toDouble(number));
  2049. const result = new BigInteger(x).gcd(y);
  2050. return new Complex(result);
  2051. }
  2052.  
  2053. /**
  2054. * Extended Euclidean algorithm.
  2055. * - Calculated as an integer.
  2056. * @param {KComplexInputData} number
  2057. * @returns {Array<Complex>} [a, b, gcd(x, y)], Result of calculating a*x + b*y = gcd(x, y).
  2058. */
  2059. extgcd(number) {
  2060. const x = Math.round(this.real);
  2061. const y = Math.round(Complex._toDouble(number));
  2062. const result = new BigInteger(x).extgcd(y);
  2063. return [new Complex(result[0]), new Complex(result[1]), new Complex(result[2])];
  2064. }
  2065.  
  2066. /**
  2067. * Least common multiple.
  2068. * - Calculated as an integer.
  2069. * @param {KComplexInputData} number
  2070. * @returns {Complex} lcm(x, y)
  2071. */
  2072. lcm(number) {
  2073. const x = Math.round(this.real);
  2074. const y = Math.round(Complex._toDouble(number));
  2075. const result = new BigInteger(x).lcm(y);
  2076. return new Complex(result);
  2077. }
  2078.  
  2079. // ----------------------
  2080. // mod
  2081. // ----------------------
  2082.  
  2083. /**
  2084. * Modular exponentiation.
  2085. * - Calculated as an integer.
  2086. * @param {KComplexInputData} exponent
  2087. * @param {KComplexInputData} m
  2088. * @returns {Complex} A^B mod m
  2089. */
  2090. modPow(exponent, m) {
  2091. const A = Math.round(this.real);
  2092. const B = Math.round(Complex._toDouble(exponent));
  2093. const m_ = Math.round(Complex._toDouble(m));
  2094. const result = new BigInteger(A).modPow(B, m_);
  2095. return new Complex(result);
  2096. }
  2097.  
  2098. /**
  2099. * Modular multiplicative inverse.
  2100. * - Calculated as an integer.
  2101. * @param {KComplexInputData} m
  2102. * @returns {Complex} A^(-1) mod m
  2103. */
  2104. modInverse(m) {
  2105. const A = Math.round(this.real);
  2106. const m_ = Math.round(Complex._toDouble(m));
  2107. const result = new BigInteger(A).modInverse(m_);
  2108. return new Complex(result);
  2109. }
  2110. // ----------------------
  2111. // その他の演算
  2112. // ----------------------
  2113. /**
  2114. * Multiply a multiple of ten.
  2115. * @param {KComplexInputData} n
  2116. * @returns {Complex} x * 10^n
  2117. */
  2118. scaleByPowerOfTen(n) {
  2119. return this.mul(Complex.TEN.pow(n));
  2120. }
  2121.  
  2122. // ----------------------
  2123. // 素数
  2124. // ----------------------
  2125. /**
  2126. * Return true if the value is prime number.
  2127. * - Calculated as an integer.
  2128. * - Calculate up to `9007199254740991`.
  2129. * @returns {boolean} - If the calculation range is exceeded, null is returned.
  2130. */
  2131. isPrime() {
  2132. const src = new BigInteger(Math.round(this.real));
  2133. return src.isPrime();
  2134. }
  2135. /**
  2136. * Return true if the value is prime number by Miller-Labin prime number determination method.
  2137. *
  2138. * Attention : it takes a very long time to process.
  2139. * - Calculated as an integer.
  2140. * @param {KComplexInputData} [certainty=100] - Repeat count (prime precision).
  2141. * @returns {boolean}
  2142. */
  2143. isProbablePrime(certainty) {
  2144. const src = new BigInteger(Math.round(this.real));
  2145. return src.isProbablePrime(certainty !== undefined ? Math.round(Complex._toDouble(certainty)) : undefined);
  2146. }
  2147.  
  2148. /**
  2149. * Next prime.
  2150. * @param {KComplexInputData} [certainty=100] - Repeat count (prime precision).
  2151. * @param {KComplexInputData} [search_max=100000] - Search range of next prime.
  2152. * @returns {Complex}
  2153. */
  2154. nextProbablePrime(certainty, search_max) {
  2155. const src = new BigInteger(Math.round(this.real));
  2156. const p1 = certainty !== undefined ? Math.round(Complex._toDouble(certainty)) : undefined;
  2157. const p2 = search_max !== undefined ? Math.round(Complex._toDouble(search_max)) : undefined;
  2158. return new Complex(src.nextProbablePrime(p1, p2));
  2159. }
  2160.  
  2161. // ----------------------
  2162. // 定数
  2163. // ----------------------
  2164. /**
  2165. * 1
  2166. * @returns {Complex} 1
  2167. */
  2168. static get ONE() {
  2169. return DEFINE.ONE;
  2170. }
  2171. /**
  2172. * 2
  2173. * @returns {Complex} 2
  2174. */
  2175. static get TWO() {
  2176. return DEFINE.TWO;
  2177. }
  2178. /**
  2179. * 10
  2180. * @returns {Complex} 10
  2181. */
  2182. static get TEN() {
  2183. return DEFINE.TEN;
  2184. }
  2185. /**
  2186. * 0
  2187. * @returns {Complex} 0
  2188. */
  2189. static get ZERO() {
  2190. return DEFINE.ZERO;
  2191. }
  2192.  
  2193. /**
  2194. * -1
  2195. * @returns {Complex} -1
  2196. */
  2197. static get MINUS_ONE() {
  2198. return DEFINE.MINUS_ONE;
  2199. }
  2200.  
  2201. /**
  2202. * i, j
  2203. * @returns {Complex} i
  2204. */
  2205. static get I() {
  2206. return DEFINE.I;
  2207. }
  2208.  
  2209. /**
  2210. * - i, - j
  2211. * @returns {Complex} - i
  2212. */
  2213. static get MINUS_I() {
  2214. return DEFINE.MINUS_I;
  2215. }
  2216.  
  2217. /**
  2218. * PI.
  2219. * @returns {Complex} 3.14...
  2220. */
  2221. static get PI() {
  2222. return DEFINE.PI;
  2223. }
  2224.  
  2225. /**
  2226. * 0.25 * PI.
  2227. * @returns {Complex} 0.78...
  2228. */
  2229. static get QUARTER_PI() {
  2230. return DEFINE.QUARTER_PI;
  2231. }
  2232.  
  2233. /**
  2234. * 0.5 * PI.
  2235. * @returns {Complex} 1.57...
  2236. */
  2237. static get HALF_PI() {
  2238. return DEFINE.HALF_PI;
  2239. }
  2240.  
  2241. /**
  2242. * 2 * PI.
  2243. * @returns {Complex} 6.28...
  2244. */
  2245. static get TWO_PI() {
  2246. return DEFINE.TWO_PI;
  2247. }
  2248.  
  2249. /**
  2250. * E, Napier's constant.
  2251. * @returns {Complex} 2.71...
  2252. */
  2253. static get E() {
  2254. return DEFINE.E;
  2255. }
  2256.  
  2257. /**
  2258. * log_e(2)
  2259. * @returns {Complex} ln(2)
  2260. */
  2261. static get LN2() {
  2262. return DEFINE.LN2;
  2263. }
  2264.  
  2265. /**
  2266. * log_e(10)
  2267. * @returns {Complex} ln(10)
  2268. */
  2269. static get LN10() {
  2270. return DEFINE.LN10;
  2271. }
  2272.  
  2273. /**
  2274. * log_2(e)
  2275. * @returns {Complex} log_2(e)
  2276. */
  2277. static get LOG2E() {
  2278. return DEFINE.LOG2E;
  2279. }
  2280. /**
  2281. * log_10(e)
  2282. * @returns {Complex} log_10(e)
  2283. */
  2284. static get LOG10E() {
  2285. return DEFINE.LOG10E;
  2286. }
  2287. /**
  2288. * sqrt(2)
  2289. * @returns {Complex} sqrt(2)
  2290. */
  2291. static get SQRT2() {
  2292. return DEFINE.SQRT2;
  2293. }
  2294. /**
  2295. * sqrt(0.5)
  2296. * @returns {Complex} sqrt(0.5)
  2297. */
  2298. static get SQRT1_2() {
  2299. return DEFINE.SQRT1_2;
  2300. }
  2301. /**
  2302. * 0.5
  2303. * @returns {Complex} 0.5
  2304. */
  2305. static get HALF() {
  2306. return DEFINE.HALF;
  2307. }
  2308.  
  2309. /**
  2310. * Positive infinity.
  2311. * @returns {Complex} Infinity
  2312. */
  2313. static get POSITIVE_INFINITY() {
  2314. return DEFINE.POSITIVE_INFINITY;
  2315. }
  2316. /**
  2317. * Negative Infinity.
  2318. * @returns {Complex} -Infinity
  2319. */
  2320. static get NEGATIVE_INFINITY() {
  2321. return DEFINE.NEGATIVE_INFINITY;
  2322. }
  2323.  
  2324. /**
  2325. * Not a Number.
  2326. * @returns {Complex} NaN
  2327. */
  2328. static get NaN() {
  2329. return DEFINE.NaN;
  2330. }
  2331.  
  2332. // ----------------------
  2333. // 互換性
  2334. // ----------------------
  2335. /**
  2336. * The positive or negative sign of this number.
  2337. * - +1 if positive, -1 if negative, 0 if 0.
  2338. * @returns {Complex}
  2339. */
  2340. signum() {
  2341. return this.sign();
  2342. }
  2343.  
  2344. /**
  2345. * Subtract.
  2346. * @param {KComplexInputData} number
  2347. * @returns {Complex} A - B
  2348. */
  2349. subtract(number) {
  2350. return this.sub(number);
  2351. }
  2352.  
  2353. /**
  2354. * Multiply.
  2355. * @param {KComplexInputData} number
  2356. * @returns {Complex} A * B
  2357. */
  2358. multiply(number) {
  2359. return this.mul(number);
  2360. }
  2361.  
  2362. /**
  2363. * Divide.
  2364. * @param {KComplexInputData} number
  2365. * @returns {Complex} fix(A / B)
  2366. */
  2367. divide(number) {
  2368. return this.div(number);
  2369. }
  2370.  
  2371. /**
  2372. * Remainder of division.
  2373. * - Result has same sign as the Dividend.
  2374. * @param {KComplexInputData} number
  2375. * @returns {Complex} A % B
  2376. */
  2377. remainder(number) {
  2378. return this.rem(number);
  2379. }
  2380. /**
  2381. * To integer rounded down to the nearest.
  2382. * @returns {Complex} fix(A), trunc(A)
  2383. */
  2384. trunc() {
  2385. return this.fix();
  2386. }
  2387. }
  2388.  
  2389. /**
  2390. * Collection of constant values used in the class.
  2391. * @ignore
  2392. */
  2393. const DEFINE = {
  2394.  
  2395. /**
  2396. * 0
  2397. */
  2398. ZERO : new Complex(0),
  2399.  
  2400. /**
  2401. * 1
  2402. */
  2403. ONE : new Complex(1),
  2404.  
  2405. /**
  2406. * 2
  2407. */
  2408. TWO : new Complex(2),
  2409.  
  2410. /**
  2411. * 10
  2412. */
  2413. TEN : new Complex(10),
  2414.  
  2415. /**
  2416. * -1
  2417. */
  2418. MINUS_ONE : new Complex(-1),
  2419.  
  2420. /**
  2421. * i, j
  2422. */
  2423. I : new Complex([0, 1]),
  2424.  
  2425. /**
  2426. * - i, - j
  2427. */
  2428. MINUS_I : new Complex([0, -1]),
  2429.  
  2430. /**
  2431. * PI.
  2432. */
  2433. PI : new Complex(Math.PI),
  2434.  
  2435. /**
  2436. * 0.25 * PI.
  2437. */
  2438. QUARTER_PI : new Complex(0.25 * Math.PI),
  2439.  
  2440. /**
  2441. * 0.5 * PI.
  2442. */
  2443. HALF_PI : new Complex(0.5 * Math.PI),
  2444.  
  2445. /**
  2446. * 2 * PI.
  2447. */
  2448. TWO_PI : new Complex(2.0 * Math.PI),
  2449.  
  2450. /**
  2451. * E, Napier's constant.
  2452. */
  2453. E : new Complex(Math.E),
  2454.  
  2455. /**
  2456. * log_e(2)
  2457. */
  2458. LN2 : new Complex(Math.LN2),
  2459.  
  2460. /**
  2461. * log_e(10)
  2462. */
  2463. LN10 : new Complex(Math.LN10),
  2464.  
  2465. /**
  2466. * log_2(e)
  2467. */
  2468. LOG2E : new Complex(Math.LOG2E),
  2469.  
  2470. /**
  2471. * log_10(e)
  2472. */
  2473. LOG10E : new Complex(Math.LOG10E),
  2474.  
  2475. /**
  2476. * sqrt(2)
  2477. */
  2478. SQRT2 : new Complex(Math.SQRT2),
  2479.  
  2480. /**
  2481. * sqrt(0.5)
  2482. */
  2483. SQRT1_2 : new Complex(Math.SQRT1_2),
  2484.  
  2485. /**
  2486. * 0.5
  2487. */
  2488. HALF : new Complex(0.5),
  2489.  
  2490. /**
  2491. * Positive infinity.
  2492. */
  2493. POSITIVE_INFINITY : new Complex(Number.POSITIVE_INFINITY),
  2494.  
  2495. /**
  2496. * Negative Infinity.
  2497. */
  2498. NEGATIVE_INFINITY : new Complex(Number.NEGATIVE_INFINITY),
  2499.  
  2500. /**
  2501. * Not a Number.
  2502. */
  2503. NaN : new Complex(Number.NaN)
  2504. };
  2505.