├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── __tests__ └── functions │ └── abs.spec.ts ├── compiler ├── binary.ts ├── call.ts ├── compile.ts ├── expressions.ts ├── generate.ts ├── grammar.ne ├── parse.ts └── unary.ts ├── complex.ts ├── docs ├── assets │ ├── css │ │ └── main.css │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.js ├── classes │ └── complex.html ├── clover.xml ├── coverage-final.json ├── globals.html ├── index.html ├── interfaces │ └── icontext.html ├── lcov-report │ ├── base.css │ ├── block-navigation.js │ ├── complex-js │ │ ├── compiler │ │ │ ├── binary.ts.html │ │ │ ├── call.ts.html │ │ │ ├── compile.ts.html │ │ │ ├── expressions.ts.html │ │ │ ├── generate.ts.html │ │ │ ├── index.html │ │ │ ├── parse.ts.html │ │ │ └── unary.ts.html │ │ ├── complex.ts.html │ │ ├── functions │ │ │ ├── abs.ts.html │ │ │ ├── acos.ts.html │ │ │ ├── acosh.ts.html │ │ │ ├── arg.ts.html │ │ │ ├── asin.ts.html │ │ │ ├── asinh.ts.html │ │ │ ├── atan.ts.html │ │ │ ├── atanh.ts.html │ │ │ ├── cbrt.ts.html │ │ │ ├── ceil.ts.html │ │ │ ├── conj.ts.html │ │ │ ├── cos.ts.html │ │ │ ├── cosh.ts.html │ │ │ ├── cube.ts.html │ │ │ ├── exp.ts.html │ │ │ ├── floor.ts.html │ │ │ ├── from.ts.html │ │ │ ├── imag.ts.html │ │ │ ├── index.html │ │ │ ├── log.ts.html │ │ │ ├── neg.ts.html │ │ │ ├── not.ts.html │ │ │ ├── polar.ts.html │ │ │ ├── random.ts.html │ │ │ ├── real.ts.html │ │ │ ├── round.ts.html │ │ │ ├── sign.ts.html │ │ │ ├── sin.ts.html │ │ │ ├── sinh.ts.html │ │ │ ├── sqrt.ts.html │ │ │ ├── square.ts.html │ │ │ ├── tan.ts.html │ │ │ ├── tanh.ts.html │ │ │ └── trunc.ts.html │ │ ├── index.html │ │ ├── internal │ │ │ ├── absImpl.ts.html │ │ │ ├── argImpl.ts.html │ │ │ ├── imagImpl.ts.html │ │ │ ├── index.html │ │ │ └── realImpl.ts.html │ │ └── methods │ │ │ ├── add.ts.html │ │ │ ├── and.ts.html │ │ │ ├── div.ts.html │ │ │ ├── equals.ts.html │ │ │ ├── getAbs.ts.html │ │ │ ├── getArg.ts.html │ │ │ ├── getImag.ts.html │ │ │ ├── getReal.ts.html │ │ │ ├── index.html │ │ │ ├── mod.ts.html │ │ │ ├── mul.ts.html │ │ │ ├── or.ts.html │ │ │ ├── pow.ts.html │ │ │ ├── sal.ts.html │ │ │ ├── sar.ts.html │ │ │ ├── shr.ts.html │ │ │ ├── sub.ts.html │ │ │ ├── toString.ts.html │ │ │ └── xor.ts.html │ ├── favicon.png │ ├── index.html │ ├── prettify.css │ ├── prettify.js │ ├── sort-arrow-sprite.png │ └── sorter.js └── lcov.info ├── functions ├── abs.ts ├── acos.ts ├── acosh.ts ├── arg.ts ├── asin.ts ├── asinh.ts ├── atan.ts ├── atanh.ts ├── cbrt.ts ├── ceil.ts ├── conj.ts ├── cos.ts ├── cosh.ts ├── cube.ts ├── exp.ts ├── floor.ts ├── from.ts ├── imag.ts ├── log.ts ├── neg.ts ├── not.ts ├── polar.ts ├── random.ts ├── real.ts ├── round.ts ├── sign.ts ├── sin.ts ├── sinh.ts ├── sqrt.ts ├── square.ts ├── tan.ts ├── tanh.ts └── trunc.ts ├── internal ├── absImpl.ts ├── argImpl.ts ├── complex.ts ├── imagImpl.ts ├── mask.ts └── realImpl.ts ├── jest.config.js ├── methods ├── add.ts ├── and.ts ├── div.ts ├── equals.ts ├── getAbs.ts ├── getArg.ts ├── getImag.ts ├── getReal.ts ├── mod.ts ├── mul.ts ├── or.ts ├── pow.ts ├── sal.ts ├── sar.ts ├── shr.ts ├── sub.ts ├── toString.ts └── xor.ts ├── package-lock.json ├── package.json ├── rollup.config.js ├── tsconfig.json ├── tslint.json └── typedoc.json /.gitignore: -------------------------------------------------------------------------------- 1 | compiler/grammar.ts 2 | dst 3 | node_modules 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | __tests__ 2 | compiler 3 | docs 4 | functions 5 | internal 6 | methods 7 | .gitignore 8 | complex.ts 9 | jest.config.js 10 | rollup.config.js 11 | typedoc.json 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Patrick Roberts 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without restriction, 6 | including without limitation the rights to use, copy, modify, 7 | merge, publish, distribute, sublicense, and/or sell copies of the 8 | Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 16 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 | OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![complex-js logo](https://raw.githubusercontent.com/patrickroberts/complex-js/assets/logo.png) 2 | 3 | ## Overview 4 | 5 | * [Getting Started](#getting-started) 6 | * [Documentation](#documentation) 7 | * [Code Coverage](#code-coverage) 8 | * [License](#license) 9 | 10 | ## Getting Started 11 | 12 | To install via [`npm`](https://www.npmjs.com/package/complex-js): 13 | 14 | ```sh 15 | npm i complex-js moo nearley # peer dependencies for expression parser 16 | ``` 17 | 18 | [Node.js](https://nodejs.org): 19 | 20 | ```js 21 | const Complex = require('complex-js'); 22 | ``` 23 | 24 | ES2015 Module: 25 | 26 | ```js 27 | import Complex from 'complex-js'; 28 | ``` 29 | 30 | Browser: 31 | 32 | ```html 33 | 34 | 37 | ``` 38 | 39 | [RequireJS](https://requirejs.org/docs/whyamd.html): 40 | 41 | ```js 42 | requirejs(['complex-js'], function (Complex) { 43 | 44 | }); 45 | ``` 46 | 47 | ## Documentation 48 | 49 | API reference available at https://patrickroberts.github.io/complex-js/. 50 | 51 | ## Code Coverage 52 | 53 | Report available at https://patrickroberts.github.io/complex-js/lcov-report/. 54 | 55 | ## License 56 | 57 | Copyright (c) 2020 Patrick Roberts 58 | 59 | MIT 60 | -------------------------------------------------------------------------------- /__tests__/functions/abs.spec.ts: -------------------------------------------------------------------------------- 1 | import abs from '../../functions/abs'; 2 | import { IComplex } from '../../internal/complex'; 3 | import mask from '../../internal/mask'; 4 | 5 | const Complex = jest.fn(); 6 | 7 | describe('abs(x)', () => { 8 | it('computes abs(a)', () => { 9 | abs(Complex, -4); 10 | 11 | expect(Complex).toBeCalledWith(4, 0, 4, 0, mask.HAS_ALL); 12 | }); 13 | 14 | it('computes abs(a, b)', () => { 15 | abs(Complex, 0, 2); 16 | 17 | expect(Complex).toBeCalledWith(2, 0, 2, 0, mask.HAS_ALL); 18 | }); 19 | 20 | it('computes abs(a+b*i)', () => { 21 | const cartesian = { _real: -5, _imag: 12, _abs: NaN, _arg: NaN, _mask: mask.HAS_CARTESIAN }; 22 | 23 | abs(Complex, cartesian); 24 | 25 | expect(Complex).toBeCalledWith(13, 0, 13, 0, mask.HAS_ALL); 26 | expect(cartesian).toMatchObject({ _abs: 13, _arg: NaN, _mask: mask.HAS_CARTESIAN | mask.HAS_ABS }); 27 | }); 28 | 29 | it('computes abs(a*e**(b*i))', () => { 30 | const polar = { _real: NaN, _imag: NaN, _abs: 3, _arg: 1, _mask: mask.HAS_POLAR }; 31 | 32 | abs(Complex, polar); 33 | 34 | expect(Complex).toBeCalledWith(3, 0, 3, 0, mask.HAS_ALL); 35 | expect(polar).toMatchObject({ _real: NaN, _imag: NaN, _mask: mask.HAS_POLAR }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /compiler/binary.ts: -------------------------------------------------------------------------------- 1 | import add from '../methods/add'; 2 | import and from '../methods/and'; 3 | import div from '../methods/div'; 4 | import mod from '../methods/mod'; 5 | import mul from '../methods/mul'; 6 | import or from '../methods/or'; 7 | import pow from '../methods/pow'; 8 | import sal from '../methods/sal'; 9 | import sar from '../methods/sar'; 10 | import shr from '../methods/shr'; 11 | import sub from '../methods/sub'; 12 | import xor from '../methods/xor'; 13 | 14 | export const binaryLookup = { 15 | '%': mod, 16 | '&': and, 17 | '*': mul, 18 | '**': pow, 19 | '+': add, 20 | '-': sub, 21 | '/': div, 22 | '<<': sal, 23 | '>>': sar, 24 | '>>>': shr, 25 | '^': xor, 26 | '|': or 27 | }; 28 | 29 | export type Binary = typeof binaryLookup; 30 | -------------------------------------------------------------------------------- /compiler/call.ts: -------------------------------------------------------------------------------- 1 | import abs from '../functions/abs'; 2 | import acos from '../functions/acos'; 3 | import acosh from '../functions/acosh'; 4 | import arg from '../functions/arg'; 5 | import asin from '../functions/asin'; 6 | import asinh from '../functions/asinh'; 7 | import atan from '../functions/atan'; 8 | import atanh from '../functions/atanh'; 9 | import cbrt from '../functions/cbrt'; 10 | import ceil from '../functions/ceil'; 11 | import conj from '../functions/conj'; 12 | import cos from '../functions/cos'; 13 | import cosh from '../functions/cosh'; 14 | import cube from '../functions/cube'; 15 | import exp from '../functions/exp'; 16 | import floor from '../functions/floor'; 17 | import imag from '../functions/imag'; 18 | import log from '../functions/log'; 19 | import random from '../functions/random'; 20 | import real from '../functions/real'; 21 | import round from '../functions/round'; 22 | import sign from '../functions/sign'; 23 | import sin from '../functions/sin'; 24 | import sinh from '../functions/sinh'; 25 | import sqrt from '../functions/sqrt'; 26 | import square from '../functions/square'; 27 | import tan from '../functions/tan'; 28 | import tanh from '../functions/tanh'; 29 | import trunc from '../functions/trunc'; 30 | 31 | export const callLookup = { 32 | abs, 33 | acos, 34 | acosh, 35 | arg, 36 | asin, 37 | asinh, 38 | atan, 39 | atanh, 40 | cbrt, 41 | ceil, 42 | conj, 43 | cos, 44 | cosh, 45 | cube, 46 | exp, 47 | floor, 48 | imag, 49 | log, 50 | random, 51 | real, 52 | round, 53 | sign, 54 | sin, 55 | sinh, 56 | sqrt, 57 | square, 58 | tan, 59 | tanh, 60 | trunc 61 | }; 62 | 63 | export type Call = typeof callLookup; 64 | -------------------------------------------------------------------------------- /compiler/compile.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import { Reviver } from './expressions'; 3 | import generate from './generate'; 4 | 5 | export default function compile( 6 | Complex: IComplexConstructor, 7 | text: string, 8 | reviver?: Reviver 9 | ): (...args: U) => T { 10 | const variable = generate(Complex, text); 11 | 12 | if (reviver) { 13 | return (...args): T => variable(reviver(...args)); 14 | } 15 | 16 | const z = variable({}); 17 | 18 | return () => z; 19 | } 20 | -------------------------------------------------------------------------------- /compiler/expressions.ts: -------------------------------------------------------------------------------- 1 | import from from '../functions/from'; 2 | import { IComplex, IComplexConstructor } from '../internal/complex'; 3 | import { Binary, binaryLookup } from './binary'; 4 | import { callLookup } from './call'; 5 | import { Unary, unaryLookup } from './unary'; 6 | 7 | export interface IContext { 8 | [identifierName: string]: T; 9 | } 10 | 11 | export type Variable = (context: IContext) => T; 12 | 13 | type Constant = () => T; 14 | 15 | export type Reviver = (...args: U) => IContext; 16 | 17 | function isConstant(param: Variable): param is Constant { 18 | return param.length === 0; 19 | } 20 | 21 | function areConstant(params: Variable[]): params is Constant[] { 22 | return params.every(isConstant); 23 | } 24 | 25 | export type Expression = (Complex: IComplexConstructor) => Variable; 26 | 27 | export const literal = (data: unknown[]): Expression => { 28 | const [numericLiteral] = data; 29 | 30 | return (Complex: IComplexConstructor): Constant => { 31 | const z = from(Complex, Number(numericLiteral)); 32 | 33 | return (): T => z; 34 | }; 35 | }; 36 | 37 | function isIndex(key: string | number | symbol, lookup: T): key is keyof T { 38 | const o = Object(lookup); 39 | return key in o && o[key] !== undefined; 40 | } 41 | 42 | function throwInvalidIdentifierName(name: string): never { 43 | throw new ReferenceError(`${name} is not defined`); 44 | } 45 | 46 | export const identifier = (data: unknown[]): Expression => { 47 | const [identifierName] = data; 48 | const { text } = identifierName as { text: string }; 49 | 50 | return () => (context: IContext): T => { 51 | if (!isIndex(text, context)) { 52 | throwInvalidIdentifierName(text); 53 | } 54 | 55 | return context[text]; 56 | }; 57 | }; 58 | 59 | function throwInvalidCallExpression(name: string): never { 60 | throw new ReferenceError(`${name} is not a function`); 61 | } 62 | 63 | function concat(t: T, u: U[]): [T, ...U[]] { 64 | return [t as T | U].concat(u) as [T, ...U[]]; 65 | } 66 | 67 | export const call = (data: unknown[]): Expression => { 68 | const [identifierName, , expressions] = data; 69 | const { text } = identifierName as { text: string }; 70 | 71 | if (!isIndex(text, callLookup)) { 72 | throwInvalidCallExpression(text); 73 | } 74 | 75 | return (Complex: IComplexConstructor) => { 76 | const fn = callLookup[text] as (Complex: IComplexConstructor, ...args: T[]) => T; 77 | const variables = (expressions as Expression[]).map(expression => expression(Complex)); 78 | 79 | if (areConstant(variables)) { 80 | const args = concat( 81 | Complex, 82 | variables.map( 83 | constant => constant() 84 | ) 85 | ); 86 | const z = fn(...args); 87 | 88 | return () => z; 89 | } 90 | 91 | return (context: IContext) => { 92 | const args = concat( 93 | Complex, 94 | variables.map( 95 | variable => variable(context) 96 | ) 97 | ); 98 | 99 | return fn(...args); 100 | }; 101 | }; 102 | }; 103 | 104 | export const unary = (data: unknown[]): Expression => { 105 | const [punctuator, , expression] = data; 106 | 107 | return Complex => { 108 | const fn = unaryLookup[punctuator as keyof Unary]; 109 | const variable = (expression as Expression)(Complex); 110 | 111 | if (isConstant(variable)) { 112 | const z = fn(Complex, variable()); 113 | 114 | return () => z; 115 | } 116 | 117 | return context => fn(Complex, variable(context)); 118 | }; 119 | }; 120 | 121 | export const binary = (data: unknown[]): Expression => { 122 | const [lhsExpression, , punctuator, , rhsExpression] = data; 123 | 124 | return Complex => { 125 | const fn = binaryLookup[punctuator as keyof Binary]; 126 | const lhs = (lhsExpression as Expression)(Complex); 127 | const rhs = (rhsExpression as Expression)(Complex); 128 | 129 | if (isConstant(lhs) && isConstant(rhs)) { 130 | const z = fn(Complex, lhs(), rhs()); 131 | 132 | return () => z; 133 | } 134 | 135 | return context => fn(Complex, lhs(context), rhs(context)); 136 | }; 137 | }; 138 | -------------------------------------------------------------------------------- /compiler/generate.ts: -------------------------------------------------------------------------------- 1 | import { Grammar, Parser } from 'nearley'; 2 | import { IComplex, IComplexConstructor } from '../internal/complex'; 3 | import { Expression, Variable } from './expressions'; 4 | import grammar from './grammar'; 5 | 6 | const rules = Grammar.fromCompiled(grammar); 7 | 8 | export default function generate(Complex: IComplexConstructor, text: string): Variable { 9 | const parser = new Parser(rules); 10 | const { results } = parser.feed(text); 11 | 12 | switch (results.length) { 13 | case 0: 14 | throw new Error('Unexpected end of input'); 15 | case 1: 16 | const [expression]: Expression[] = results; 17 | return expression(Complex); 18 | default: 19 | throw new Error('Ambiguous grammar'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/grammar.ne: -------------------------------------------------------------------------------- 1 | @preprocessor typescript 2 | 3 | @{% 4 | import moo from 'moo'; 5 | import { literal, identifier, call, unary, binary } from './expressions'; 6 | 7 | const pick = (idx: number) => (data: any[]) => data[idx]; 8 | const empty = () => []; 9 | const array = (...idx: number[]) => (data: any[]) => idx.map(i => data[i]); 10 | const reduce = (acc: number, cur: number) => (data: any[]) => data[acc].concat(data[cur]); 11 | const dispose = () => null; 12 | 13 | const lexer = moo.compile({ 14 | WhiteSpace: / +/, 15 | IdentifierName: /[$A-Z_a-z][$\w]*/, 16 | DecimalLiteral: /(?:(?:0|[1-9]\d*)\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?/, 17 | BinaryIntegerLiteral: /0[Bb][01]+/, 18 | OctalIntegerLiteral: /0[Oo][0-7]+/, 19 | HexIntegerLiteral: /0[Xx][\dA-Fa-f]+/, 20 | // include update punctuators ++ and -- to enforce whitespace between sequential + and - punctuators 21 | Punctuator: ['(', ')', '[', ']', '.', ',', '+', '-', '*', '/', '%', '**', '++', '--', '<<', '>>', '>>>', '&', '|', '^', '~'], 22 | }); 23 | 24 | // use interface declaration merging to resolve type mismatch between nearley NearleyToken and moo Token 25 | interface NearleyToken { 26 | offset: number; 27 | text: string; 28 | lineBreaks: number; 29 | line: number; 30 | col: number; 31 | } 32 | %} 33 | 34 | @lexer lexer 35 | 36 | Expression -> 37 | _ BitwiseORExpression _ {% pick(1) %} 38 | 39 | BitwiseORExpression -> 40 | BitwiseORExpression _ "|" _ BitwiseXORExpression {% binary %} 41 | | BitwiseXORExpression {% id %} 42 | 43 | BitwiseXORExpression -> 44 | BitwiseXORExpression _ "^" _ BitwiseANDExpression {% binary %} 45 | | BitwiseANDExpression {% id %} 46 | 47 | BitwiseANDExpression -> 48 | BitwiseANDExpression _ "&" _ ShiftExpression {% binary %} 49 | | ShiftExpression {% id %} 50 | 51 | ShiftExpression -> 52 | ShiftExpression _ ShiftOperator _ AdditiveExpression {% binary %} 53 | | AdditiveExpression {% id %} 54 | 55 | ShiftOperator -> 56 | "<<" {% id %} 57 | | ">>" {% id %} 58 | | ">>>" {% id %} 59 | 60 | AdditiveExpression -> 61 | AdditiveExpression _ AdditiveOperator _ MultiplicativeExpression {% binary %} 62 | | MultiplicativeExpression {% id %} 63 | 64 | AdditiveOperator -> 65 | "+" {% id %} 66 | | "-" {% id %} 67 | 68 | MultiplicativeExpression -> 69 | MultiplicativeExpression _ MultiplicativeOperator _ ExponentiationExpression {% binary %} 70 | | ExponentiationExpression {% id %} 71 | 72 | MultiplicativeOperator -> 73 | "*" {% id %} 74 | | "/" {% id %} 75 | | "%" {% id %} 76 | 77 | ExponentiationExpression -> 78 | LeftHandSideExpression _ "**" _ ExponentiationExpression {% binary %} 79 | | UnaryExpression {% id %} 80 | 81 | UnaryExpression -> 82 | UnaryOperator _ UnaryExpression {% unary %} 83 | | LeftHandSideExpression {% id %} 84 | 85 | UnaryOperator -> 86 | "+" {% id %} 87 | | "-" {% id %} 88 | | "~" {% id %} 89 | 90 | LeftHandSideExpression -> 91 | ParenthesizedExpression {% id %} 92 | | PrimaryExpression {% id %} 93 | 94 | ParenthesizedExpression -> 95 | "(" _ BitwiseORExpression _ ")" {% pick(2) %} 96 | | "[" _ BitwiseORExpression _ "]" {% pick(2) %} 97 | 98 | PrimaryExpression -> 99 | CallExpression {% id %} 100 | | %IdentifierName {% identifier %} 101 | | NumericLiteral {% literal %} 102 | 103 | NumericLiteral -> 104 | %DecimalLiteral {% id %} 105 | | %BinaryIntegerLiteral {% id %} 106 | | %OctalIntegerLiteral {% id %} 107 | | %HexIntegerLiteral {% id %} 108 | 109 | CallExpression -> 110 | %IdentifierName _ Arguments {% call %} 111 | 112 | Arguments -> 113 | "(" _ ArgumentList _ ")" {% pick(2) %} 114 | | "(" _ ")" {% empty %} 115 | 116 | ArgumentList -> 117 | ArgumentList _ "," _ BitwiseORExpression {% reduce(0, 4) %} 118 | | BitwiseORExpression {% array(0) %} 119 | 120 | _ -> 121 | %WhiteSpace:? {% dispose %} 122 | -------------------------------------------------------------------------------- /compiler/parse.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import { IContext } from './expressions'; 3 | import generate from './generate'; 4 | 5 | export default function parse(Complex: IComplexConstructor, text: string, context?: IContext): T { 6 | const variable = generate(Complex, text); 7 | 8 | return variable(context!); 9 | } 10 | -------------------------------------------------------------------------------- /compiler/unary.ts: -------------------------------------------------------------------------------- 1 | import from from '../functions/from'; 2 | import neg from '../functions/neg'; 3 | import not from '../functions/not'; 4 | 5 | export type Unary = typeof unaryLookup; 6 | 7 | export const unaryLookup = { 8 | '+': from, 9 | '-': neg, 10 | '~': not 11 | }; 12 | -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | height: 100%; 4 | } 5 | body { 6 | font-family: Helvetica Neue, Helvetica, Arial; 7 | font-size: 14px; 8 | color:#333; 9 | } 10 | .small { font-size: 12px; } 11 | *, *:after, *:before { 12 | -webkit-box-sizing:border-box; 13 | -moz-box-sizing:border-box; 14 | box-sizing:border-box; 15 | } 16 | h1 { font-size: 20px; margin: 0;} 17 | h2 { font-size: 14px; } 18 | pre { 19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; 20 | margin: 0; 21 | padding: 0; 22 | -moz-tab-size: 2; 23 | -o-tab-size: 2; 24 | tab-size: 2; 25 | } 26 | a { color:#0074D9; text-decoration:none; } 27 | a:hover { text-decoration:underline; } 28 | .strong { font-weight: bold; } 29 | .space-top1 { padding: 10px 0 0 0; } 30 | .pad2y { padding: 20px 0; } 31 | .pad1y { padding: 10px 0; } 32 | .pad2x { padding: 0 20px; } 33 | .pad2 { padding: 20px; } 34 | .pad1 { padding: 10px; } 35 | .space-left2 { padding-left:55px; } 36 | .space-right2 { padding-right:20px; } 37 | .center { text-align:center; } 38 | .clearfix { display:block; } 39 | .clearfix:after { 40 | content:''; 41 | display:block; 42 | height:0; 43 | clear:both; 44 | visibility:hidden; 45 | } 46 | .fl { float: left; } 47 | @media only screen and (max-width:640px) { 48 | .col3 { width:100%; max-width:100%; } 49 | .hide-mobile { display:none!important; } 50 | } 51 | 52 | .quiet { 53 | color: #7f7f7f; 54 | color: rgba(0,0,0,0.5); 55 | } 56 | .quiet a { opacity: 0.7; } 57 | 58 | .fraction { 59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; 60 | font-size: 10px; 61 | color: #555; 62 | background: #E8E8E8; 63 | padding: 4px 5px; 64 | border-radius: 3px; 65 | vertical-align: middle; 66 | } 67 | 68 | div.path a:link, div.path a:visited { color: #333; } 69 | table.coverage { 70 | border-collapse: collapse; 71 | margin: 10px 0 0 0; 72 | padding: 0; 73 | } 74 | 75 | table.coverage td { 76 | margin: 0; 77 | padding: 0; 78 | vertical-align: top; 79 | } 80 | table.coverage td.line-count { 81 | text-align: right; 82 | padding: 0 5px 0 20px; 83 | } 84 | table.coverage td.line-coverage { 85 | text-align: right; 86 | padding-right: 10px; 87 | min-width:20px; 88 | } 89 | 90 | table.coverage td span.cline-any { 91 | display: inline-block; 92 | padding: 0 5px; 93 | width: 100%; 94 | } 95 | .missing-if-branch { 96 | display: inline-block; 97 | margin-right: 5px; 98 | border-radius: 3px; 99 | position: relative; 100 | padding: 0 4px; 101 | background: #333; 102 | color: yellow; 103 | } 104 | 105 | .skip-if-branch { 106 | display: none; 107 | margin-right: 10px; 108 | position: relative; 109 | padding: 0 4px; 110 | background: #ccc; 111 | color: white; 112 | } 113 | .missing-if-branch .typ, .skip-if-branch .typ { 114 | color: inherit !important; 115 | } 116 | .coverage-summary { 117 | border-collapse: collapse; 118 | width: 100%; 119 | } 120 | .coverage-summary tr { border-bottom: 1px solid #bbb; } 121 | .keyline-all { border: 1px solid #ddd; } 122 | .coverage-summary td, .coverage-summary th { padding: 10px; } 123 | .coverage-summary tbody { border: 1px solid #bbb; } 124 | .coverage-summary td { border-right: 1px solid #bbb; } 125 | .coverage-summary td:last-child { border-right: none; } 126 | .coverage-summary th { 127 | text-align: left; 128 | font-weight: normal; 129 | white-space: nowrap; 130 | } 131 | .coverage-summary th.file { border-right: none !important; } 132 | .coverage-summary th.pct { } 133 | .coverage-summary th.pic, 134 | .coverage-summary th.abs, 135 | .coverage-summary td.pct, 136 | .coverage-summary td.abs { text-align: right; } 137 | .coverage-summary td.file { white-space: nowrap; } 138 | .coverage-summary td.pic { min-width: 120px !important; } 139 | .coverage-summary tfoot td { } 140 | 141 | .coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | .coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | .coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | .status-line { height: 10px; } 155 | /* yellow */ 156 | .cbranch-no { background: yellow !important; color: #111; } 157 | /* dark red */ 158 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } 159 | .low .chart { border:1px solid #C21F39 } 160 | .highlighted, 161 | .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ 162 | background: #C21F39 !important; 163 | } 164 | /* medium red */ 165 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } 166 | /* light red */ 167 | .low, .cline-no { background:#FCE1E5 } 168 | /* light green */ 169 | .high, .cline-yes { background:rgb(230,245,208) } 170 | /* medium green */ 171 | .cstat-yes { background:rgb(161,215,106) } 172 | /* dark green */ 173 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) } 174 | .high .chart { border:1px solid rgb(77,146,33) } 175 | /* dark yellow (gold) */ 176 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; } 177 | .medium .chart { border:1px solid #f9cd0b; } 178 | /* light yellow */ 179 | .medium { background: #fff4c2; } 180 | 181 | .cstat-skip { background: #ddd; color: #111; } 182 | .fstat-skip { background: #ddd; color: #111 !important; } 183 | .cbranch-skip { background: #ddd !important; color: #111; } 184 | 185 | span.cline-neutral { background: #eaeaea; } 186 | 187 | .coverage-summary td.empty { 188 | opacity: .5; 189 | padding-top: 4px; 190 | padding-bottom: 4px; 191 | line-height: 1; 192 | color: #888; 193 | } 194 | 195 | .cover-fill, .cover-empty { 196 | display:inline-block; 197 | height: 12px; 198 | } 199 | .chart { 200 | line-height: 0; 201 | } 202 | .cover-empty { 203 | background: white; 204 | } 205 | .cover-full { 206 | border-right: none !important; 207 | } 208 | pre.prettyprint { 209 | border: none !important; 210 | padding: 0 !important; 211 | margin: 0 !important; 212 | } 213 | .com { color: #999 !important; } 214 | .ignore-none { color: #999; font-weight: normal; } 215 | 216 | .wrapper { 217 | min-height: 100%; 218 | height: auto !important; 219 | height: 100%; 220 | margin: 0 auto -48px; 221 | } 222 | .footer, .push { 223 | height: 48px; 224 | } 225 | -------------------------------------------------------------------------------- /docs/lcov-report/block-navigation.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var jumpToCode = (function init() { 3 | // Classes of code we would like to highlight in the file view 4 | var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; 5 | 6 | // Elements to highlight in the file listing view 7 | var fileListingElements = ['td.pct.low']; 8 | 9 | // We don't want to select elements that are direct descendants of another match 10 | var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` 11 | 12 | // Selecter that finds elements on the page to which we can jump 13 | var selector = 14 | fileListingElements.join(', ') + 15 | ', ' + 16 | notSelector + 17 | missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` 18 | 19 | // The NodeList of matching elements 20 | var missingCoverageElements = document.querySelectorAll(selector); 21 | 22 | var currentIndex; 23 | 24 | function toggleClass(index) { 25 | missingCoverageElements 26 | .item(currentIndex) 27 | .classList.remove('highlighted'); 28 | missingCoverageElements.item(index).classList.add('highlighted'); 29 | } 30 | 31 | function makeCurrent(index) { 32 | toggleClass(index); 33 | currentIndex = index; 34 | missingCoverageElements.item(index).scrollIntoView({ 35 | behavior: 'smooth', 36 | block: 'center', 37 | inline: 'center' 38 | }); 39 | } 40 | 41 | function goToPrevious() { 42 | var nextIndex = 0; 43 | if (typeof currentIndex !== 'number' || currentIndex === 0) { 44 | nextIndex = missingCoverageElements.length - 1; 45 | } else if (missingCoverageElements.length > 1) { 46 | nextIndex = currentIndex - 1; 47 | } 48 | 49 | makeCurrent(nextIndex); 50 | } 51 | 52 | function goToNext() { 53 | var nextIndex = 0; 54 | 55 | if ( 56 | typeof currentIndex === 'number' && 57 | currentIndex < missingCoverageElements.length - 1 58 | ) { 59 | nextIndex = currentIndex + 1; 60 | } 61 | 62 | makeCurrent(nextIndex); 63 | } 64 | 65 | return function jump(event) { 66 | switch (event.which) { 67 | case 78: // n 68 | case 74: // j 69 | goToNext(); 70 | break; 71 | case 66: // b 72 | case 75: // k 73 | case 80: // p 74 | goToPrevious(); 75 | break; 76 | } 77 | }; 78 | })(); 79 | window.addEventListener('keydown', jumpToCode); 80 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/compiler/parse.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/compiler/parse.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/compiler parse.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/4 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 0/0 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/4 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10  70 |   71 |   72 |   73 |   74 |   75 |   76 |   77 |   78 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 79 | import { IContext } from './expressions';
 80 | import generate from './generate';
 81 |  
 82 | export default function parse<T extends IComplex>(Complex: IComplexConstructor<T>, text: string, context?: IContext<T>): T {
 83 |   const variable = generate(Complex, text);
 84 |  
 85 |   return variable(context!);
 86 | }
 87 |  
88 | 89 |
90 |
91 | 96 | 97 | 98 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/compiler/unary.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/compiler/unary.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/compiler unary.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/4 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 0/0 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 0/0 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/4 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12  72 |   73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |   81 |   82 |  
import from from '../functions/from';
 83 | import neg from '../functions/neg';
 84 | import not from '../functions/not';
 85 |  
 86 | export type Unary = typeof unaryLookup;
 87 |  
 88 | export const unaryLookup = {
 89 |   '+': from,
 90 |   '-': neg,
 91 |   '~': not
 92 | };
 93 |  
94 | 95 |
96 |
97 | 102 | 103 | 104 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/abs.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/abs.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions abs.ts

23 |
24 | 25 |
26 | 100% 27 | Statements 28 | 5/5 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 3/3 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 1/1 43 |
44 | 45 | 46 |
47 | 100% 48 | Lines 49 | 5/5 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 131x 73 |   74 |   75 | 1x 76 |   77 | 1x 78 | 4x 79 |   80 |   81 |   82 | 4x 83 |   84 |  
import absImpl from '../internal/absImpl';
 85 | import { IComplex, IComplexConstructor } from '../internal/complex';
 86 | import mask from '../internal/mask';
 87 | import getAbs from '../methods/getAbs';
 88 |  
 89 | export default function abs<T extends IComplex>(Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
 90 |   const zAbs = typeof z === 'number'
 91 |     ? absImpl(z, i)
 92 |     : getAbs(z);
 93 |  
 94 |   return new Complex(zAbs, 0, zAbs, 0, mask.HAS_ALL);
 95 | }
 96 |  
97 | 98 |
99 |
100 | 105 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/arg.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/arg.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions arg.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/5 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/5 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/5 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19  79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |  
import argImpl from '../internal/argImpl';
 97 | import { IComplex, IComplexConstructor } from '../internal/complex';
 98 | import mask from '../internal/mask';
 99 | import getArg from '../methods/getArg';
100 |  
101 | export default function arg<T extends IComplex>(Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
102 |   const zArg = typeof z === 'number'
103 |     ? argImpl(z, i)
104 |     : getArg(z);
105 |  
106 |   return new Complex(
107 |     zArg,
108 |     0,
109 |     Math.abs(zArg),
110 |     zArg < 0 ? Math.PI : 0,
111 |     mask.HAS_ALL
112 |   );
113 | }
114 |  
115 | 116 |
117 |
118 | 123 | 124 | 125 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/asinh.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/asinh.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions asinh.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/12 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/1 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/12 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18  78 |   79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 95 | import add from '../methods/add';
 96 | import from from './from';
 97 | import log from './log';
 98 | import sqrt from './sqrt';
 99 | import square from './square';
100 |  
101 | export default function asinh<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
102 |   const ONE = from(Complex, 1);
103 |  
104 |   const square1 = square(Complex, z, i);
105 |   const add1 = add(Complex, ONE, square1);
106 |   const sqrt1 = sqrt(Complex, add1);
107 |   const add2 = add(Complex, sqrt1, z, i);
108 |   
109 |   return log(Complex, add2);
110 | }
111 |  
112 | 113 |
114 |
115 | 120 | 121 | 122 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/ceil.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/ceil.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions ceil.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/9 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/9 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20  80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 99 | import mask from '../internal/mask';
100 | import getImag from '../methods/getImag';
101 | import getReal from '../methods/getReal';
102 |  
103 | export default function ceil<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
104 |   let zReal: number
105 |   let zImag: number;
106 |  
107 |   if (typeof z === 'number') {
108 |     zReal = z;
109 |     zImag = i;
110 |   } else {
111 |     zReal = getReal(z);
112 |     zImag = getImag(z);
113 |   }
114 |  
115 |   return new Complex(Math.ceil(zReal), Math.ceil(zImag), NaN, NaN, mask.HAS_CARTESIAN);
116 | }
117 |  
118 | 119 |
120 |
121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/floor.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/floor.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions floor.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/9 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/9 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20  80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 99 | import mask from '../internal/mask';
100 | import getImag from '../methods/getImag';
101 | import getReal from '../methods/getReal';
102 |  
103 | export default function floor<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
104 |   let zReal: number;
105 |   let zImag: number;
106 |  
107 |   if (typeof z === 'number') {
108 |     zReal = z;
109 |     zImag = i;
110 |   } else {
111 |     zReal = getReal(z);
112 |     zImag = getImag(z);
113 |   }
114 |  
115 |   return new Complex(Math.floor(zReal), Math.floor(zImag), NaN, NaN, mask.HAS_CARTESIAN);
116 | }
117 |  
118 | 119 |
120 |
121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/imag.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/imag.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions imag.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/5 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/5 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/5 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19  79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 97 | import imagImpl from '../internal/imagImpl';
 98 | import mask from '../internal/mask';
 99 | import getImag from '../methods/getImag';
100 |  
101 | export default function imag<T extends IComplex>(Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
102 |   const zImag = typeof z === 'number'
103 |     ? imagImpl(z, i)
104 |     : getImag(z);
105 |  
106 |   return new Complex(
107 |     zImag,
108 |     0,
109 |     Math.abs(zImag),
110 |     zImag < 0 ? Math.PI : 0,
111 |     mask.HAS_ALL
112 |   );
113 | }
114 |  
115 | 116 |
117 |
118 | 123 | 124 | 125 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/not.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/not.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions not.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/9 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/9 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20  80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 99 | import mask from '../internal/mask';
100 | import getImag from '../methods/getImag';
101 | import getReal from '../methods/getReal';
102 |  
103 | export default function not<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
104 |   let zReal: number;
105 |   let zImag: number;
106 |  
107 |   if (typeof z === 'number') {
108 |     zReal = z;
109 |     zImag = i;
110 |   } else {
111 |     zReal = getReal(z);
112 |     zImag = getImag(z);
113 |   }
114 |  
115 |   return new Complex(~zReal, ~zImag, NaN, NaN, mask.HAS_CARTESIAN);
116 | }
117 |  
118 | 119 |
120 |
121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/polar.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/polar.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions polar.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/7 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/7 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18  78 |   79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 95 | import mask from '../internal/mask';
 96 |  
 97 | export default function polar<T extends IComplex> (Complex: IComplexConstructor<T>, abs: number, arg = 0): T {
 98 |   let zAbs: number;
 99 |   let zArg: number;
100 |  
101 |   if (abs < 0) {
102 |     zAbs = -abs;
103 |     zArg = arg + Math.PI;
104 |   } else {
105 |     zAbs = abs;
106 |     zArg = arg;
107 |   }
108 |  
109 |   return new Complex(NaN, NaN, zAbs, zArg, mask.HAS_POLAR);
110 | }
111 |  
112 | 113 |
114 |
115 | 120 | 121 | 122 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/random.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/random.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions random.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/2 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 0/0 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/2 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7  67 |   68 |   69 |   70 |   71 |   72 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
73 | import mask from '../internal/mask';
74 |  
75 | export default function random<T extends IComplex> (Complex: IComplexConstructor<T>): T {
76 |   return new Complex(Math.random(), Math.random(), NaN, NaN, mask.HAS_CARTESIAN);
77 | }
78 |  
79 | 80 |
81 |
82 | 87 | 88 | 89 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/real.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/real.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions real.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/5 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/5 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/5 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19  79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 97 | import mask from '../internal/mask';
 98 | import realImpl from '../internal/realImpl';
 99 | import getReal from '../methods/getReal';
100 |  
101 | export default function real<T extends IComplex>(Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
102 |   const zReal = typeof z === 'number'
103 |     ? realImpl(z, i)
104 |     : getReal(z);
105 |  
106 |   return new Complex(
107 |     zReal,
108 |     0,
109 |     Math.abs(zReal),
110 |     zReal < 0 ? Math.PI : 0,
111 |     mask.HAS_ALL
112 |   );
113 | }
114 |  
115 | 116 |
117 |
118 | 123 | 124 | 125 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/round.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/round.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions round.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/9 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/9 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20  80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 99 | import mask from '../internal/mask';
100 | import getImag from '../methods/getImag';
101 | import getReal from '../methods/getReal';
102 |  
103 | export default function round<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
104 |   let zReal: number;
105 |   let zImag: number;
106 |  
107 |   if (typeof z === 'number') {
108 |     zReal = z;
109 |     zImag = i;
110 |   } else {
111 |     zReal = getReal(z);
112 |     zImag = getImag(z);
113 |   }
114 |  
115 |   return new Complex(Math.round(zReal), Math.round(zImag), NaN, NaN, mask.HAS_CARTESIAN);
116 | }
117 |  
118 | 119 |
120 |
121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/functions/trunc.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/functions/trunc.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/functions trunc.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/9 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/3 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/9 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14 74 | 15 75 | 16 76 | 17 77 | 18 78 | 19 79 | 20  80 |   81 |   82 |   83 |   84 |   85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |  
import { IComplex, IComplexConstructor } from '../internal/complex';
 99 | import mask from '../internal/mask';
100 | import getImag from '../methods/getImag';
101 | import getReal from '../methods/getReal';
102 |  
103 | export default function trunc<T extends IComplex> (Complex: IComplexConstructor<T>, z: IComplex | number, i = 0): T {
104 |   let zReal: number;
105 |   let zImag: number;
106 |  
107 |   if (typeof z === 'number') {
108 |     zReal = z;
109 |     zImag = i;
110 |   } else {
111 |     zReal = getReal(z);
112 |     zImag = getImag(z);
113 |   }
114 |  
115 |   return new Complex(Math.trunc(zReal), Math.trunc(zImag), NaN, NaN, mask.HAS_CARTESIAN);
116 | }
117 |  
118 | 119 |
120 |
121 | 126 | 127 | 128 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files complex-js

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/125 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/1 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/56 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/125 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
FileStatementsBranchesFunctionsLines
complex.ts 78 |
79 |
0%0/1250%0/10%0/560%0/125
92 |
93 |
94 |
95 | 100 | 101 | 102 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/internal/absImpl.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/internal/absImpl.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/internal absImpl.ts

23 |
24 | 25 |
26 | 100% 27 | Statements 28 | 2/2 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 4/4 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 1/1 43 |
44 | 45 | 46 |
47 | 100% 48 | Lines 49 | 2/2 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 111x 71 | 3x 72 |   73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |  
export default function absImpl (real: number, imag: number): number {
 81 |   return (
 82 |     // if z is real, abs = |real|
 83 |     imag === 0 ? Math.abs(real)
 84 |     // if z is imag, abs = |imag|
 85 |     : real === 0 ? Math.abs(imag)
 86 |     // else abs = |z|
 87 |     : Math.hypot(real, imag)
 88 |   );
 89 | }
 90 |  
91 | 92 |
93 |
94 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/internal/argImpl.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/internal/argImpl.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/internal argImpl.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/2 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/8 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/2 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11  71 |   72 |   73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |  
export default function argImpl (real: number, imag: number): number {
 81 |   return (
 82 |     // if z is real, if z is negative, arg = pi, else arg = 0
 83 |     imag === 0 ? (real < 0 ? Math.PI : 0)
 84 |     // if z is imag, arg = sign(imag) * pi / 2
 85 |     : real === 0 ? (imag < 0 ? -0.5 : 0.5) * Math.PI
 86 |     // else arg = atan(imag / real)
 87 |     : Math.atan2(imag, real)
 88 |   );
 89 | }
 90 |  
91 | 92 |
93 |
94 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/internal/imagImpl.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/internal/imagImpl.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/internal imagImpl.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/2 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/4 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/2 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9  69 |   70 |   71 |   72 |   73 |   74 |   75 |   76 |  
export default function imagImpl (abs: number, arg: number): number {
 77 |   return (
 78 |     // if z is real, imag = 0
 79 |     arg === 0 || arg === Math.PI ? 0
 80 |     // else imag = abs * sin(arg)
 81 |     : abs * Math.sin(arg)
 82 |   );
 83 | }
 84 |  
85 | 86 |
87 |
88 | 93 | 94 | 95 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/internal/realImpl.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/internal/realImpl.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/internal realImpl.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/2 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/4 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/2 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11  71 |   72 |   73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |  
export default function realImpl (abs: number, arg: number): number {
 81 |   return (
 82 |     // if z is positive, real = abs
 83 |     arg === 0 ? abs
 84 |     // if z is negative, real = -abs
 85 |     : arg === Math.PI ? -abs
 86 |     // else real = abs * cos(arg)
 87 |     : abs * Math.cos(arg)
 88 |   );
 89 | }
 90 |  
91 | 92 |
93 |
94 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/methods/getAbs.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/methods/getAbs.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/methods getAbs.ts

23 |
24 | 25 |
26 | 100% 27 | Statements 28 | 6/6 29 |
30 | 31 | 32 |
33 | 100% 34 | Branches 35 | 2/2 36 |
37 | 38 | 39 |
40 | 100% 41 | Functions 42 | 1/1 43 |
44 | 45 | 46 |
47 | 100% 48 | Lines 49 | 6/6 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 131x 73 |   74 |   75 |   76 | 1x 77 | 2x 78 | 1x 79 | 1x 80 |   81 |   82 | 2x 83 |   84 |  
import absImpl from '../internal/absImpl';
 85 | import { IComplex } from '../internal/complex';
 86 | import mask from '../internal/mask';
 87 |  
 88 | export default function getAbs (z: IComplex): number {
 89 |   if (!(z._mask & mask.HAS_ABS)) {
 90 |     z._abs = absImpl(z._real, z._imag);
 91 |     z._mask |= mask.HAS_ABS;
 92 |   }
 93 |  
 94 |   return z._abs;
 95 | }
 96 |  
97 | 98 |
99 |
100 | 105 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/methods/getArg.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/methods/getArg.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/methods getArg.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/6 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/2 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/6 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13  73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |   81 |   82 |   83 |   84 |  
import argImpl from '../internal/argImpl';
 85 | import { IComplex } from '../internal/complex';
 86 | import mask from '../internal/mask';
 87 |  
 88 | export default function getArg (z: IComplex): number {
 89 |   if (!(z._mask & mask.HAS_ARG)) {
 90 |     z._arg = argImpl(z._real, z._imag);
 91 |     z._mask |= mask.HAS_ARG;
 92 |   }
 93 |  
 94 |   return z._arg;
 95 | }
 96 |  
97 | 98 |
99 |
100 | 105 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/methods/getImag.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/methods/getImag.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/methods getImag.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/6 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/2 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/6 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13  73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |   81 |   82 |   83 |   84 |  
import { IComplex } from '../internal/complex';
 85 | import imagImpl from '../internal/imagImpl';
 86 | import mask from '../internal/mask';
 87 |  
 88 | export default function getImag (z: IComplex): number {
 89 |   if (!(z._mask & mask.HAS_IMAG)) {
 90 |     z._imag = imagImpl(z._abs, z._arg);
 91 |     z._mask |= mask.HAS_IMAG;
 92 |   }
 93 |  
 94 |   return z._imag;
 95 | }
 96 |  
97 | 98 |
99 |
100 | 105 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/methods/getReal.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/methods/getReal.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/methods getReal.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/6 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/2 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/6 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13  73 |   74 |   75 |   76 |   77 |   78 |   79 |   80 |   81 |   82 |   83 |   84 |  
import { IComplex } from '../internal/complex';
 85 | import mask from '../internal/mask';
 86 | import realImpl from '../internal/realImpl';
 87 |  
 88 | export default function getReal (z: IComplex): number {
 89 |   if (!(z._mask & mask.HAS_REAL)) {
 90 |     z._real = realImpl(z._abs, z._arg);
 91 |     z._mask |= mask.HAS_REAL;
 92 |   }
 93 |  
 94 |   return z._real;
 95 | }
 96 |  
97 | 98 |
99 |
100 | 105 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/lcov-report/complex-js/methods/mod.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for complex-js/methods/mod.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / complex-js/methods mod.ts

23 |
24 | 25 |
26 | 0% 27 | Statements 28 | 0/8 29 |
30 | 31 | 32 |
33 | 0% 34 | Branches 35 | 0/1 36 |
37 | 38 | 39 |
40 | 0% 41 | Functions 42 | 0/1 43 |
44 | 45 | 46 |
47 | 0% 48 | Lines 49 | 0/8 50 |
51 | 52 | 53 |
54 |

55 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 56 |

57 |
58 |
59 |

 60 | 
1 61 | 2 62 | 3 63 | 4 64 | 5 65 | 6 66 | 7 67 | 8 68 | 9 69 | 10 70 | 11 71 | 12 72 | 13 73 | 14  74 |   75 |   76 |   77 |   78 |   79 |   80 |   81 |   82 |   83 |   84 |   85 |   86 |  
import trunc from '../functions/trunc';
 87 | import { IComplex, IComplexConstructor } from '../internal/complex';
 88 | import div from './div';
 89 | import mul from './mul';
 90 | import sub from './sub';
 91 |  
 92 | export default function mod<T extends IComplex> (Complex: IComplexConstructor<T>, lhs: IComplex, r: IComplex | number, i = 0): T {
 93 |   // lhs % rhs = lhs - (trunc(lhs / rhs) * rhs)
 94 |   const q = div(Complex, lhs, r, i);
 95 |   const p = mul(Complex, trunc(Complex, q), r, i);
 96 |  
 97 |   return sub(Complex, lhs, p);
 98 | }
 99 |  
100 | 101 |
102 |
103 | 108 | 109 | 110 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/lcov-report/favicon.png -------------------------------------------------------------------------------- /docs/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /docs/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickroberts/complex-js/eb8ee5a5b88a31140898a96e687d12967b105727/docs/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /docs/lcov-report/sorter.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var addSorting = (function() { 3 | 'use strict'; 4 | var cols, 5 | currentSort = { 6 | index: 0, 7 | desc: false 8 | }; 9 | 10 | // returns the summary table element 11 | function getTable() { 12 | return document.querySelector('.coverage-summary'); 13 | } 14 | // returns the thead element of the summary table 15 | function getTableHeader() { 16 | return getTable().querySelector('thead tr'); 17 | } 18 | // returns the tbody element of the summary table 19 | function getTableBody() { 20 | return getTable().querySelector('tbody'); 21 | } 22 | // returns the th element for nth column 23 | function getNthColumn(n) { 24 | return getTableHeader().querySelectorAll('th')[n]; 25 | } 26 | 27 | // loads all columns 28 | function loadColumns() { 29 | var colNodes = getTableHeader().querySelectorAll('th'), 30 | colNode, 31 | cols = [], 32 | col, 33 | i; 34 | 35 | for (i = 0; i < colNodes.length; i += 1) { 36 | colNode = colNodes[i]; 37 | col = { 38 | key: colNode.getAttribute('data-col'), 39 | sortable: !colNode.getAttribute('data-nosort'), 40 | type: colNode.getAttribute('data-type') || 'string' 41 | }; 42 | cols.push(col); 43 | if (col.sortable) { 44 | col.defaultDescSort = col.type === 'number'; 45 | colNode.innerHTML = 46 | colNode.innerHTML + ''; 47 | } 48 | } 49 | return cols; 50 | } 51 | // attaches a data attribute to every tr element with an object 52 | // of data values keyed by column name 53 | function loadRowData(tableRow) { 54 | var tableCols = tableRow.querySelectorAll('td'), 55 | colNode, 56 | col, 57 | data = {}, 58 | i, 59 | val; 60 | for (i = 0; i < tableCols.length; i += 1) { 61 | colNode = tableCols[i]; 62 | col = cols[i]; 63 | val = colNode.getAttribute('data-value'); 64 | if (col.type === 'number') { 65 | val = Number(val); 66 | } 67 | data[col.key] = val; 68 | } 69 | return data; 70 | } 71 | // loads all row data 72 | function loadData() { 73 | var rows = getTableBody().querySelectorAll('tr'), 74 | i; 75 | 76 | for (i = 0; i < rows.length; i += 1) { 77 | rows[i].data = loadRowData(rows[i]); 78 | } 79 | } 80 | // sorts the table using the data for the ith column 81 | function sortByIndex(index, desc) { 82 | var key = cols[index].key, 83 | sorter = function(a, b) { 84 | a = a.data[key]; 85 | b = b.data[key]; 86 | return a < b ? -1 : a > b ? 1 : 0; 87 | }, 88 | finalSorter = sorter, 89 | tableBody = document.querySelector('.coverage-summary tbody'), 90 | rowNodes = tableBody.querySelectorAll('tr'), 91 | rows = [], 92 | i; 93 | 94 | if (desc) { 95 | finalSorter = function(a, b) { 96 | return -1 * sorter(a, b); 97 | }; 98 | } 99 | 100 | for (i = 0; i < rowNodes.length; i += 1) { 101 | rows.push(rowNodes[i]); 102 | tableBody.removeChild(rowNodes[i]); 103 | } 104 | 105 | rows.sort(finalSorter); 106 | 107 | for (i = 0; i < rows.length; i += 1) { 108 | tableBody.appendChild(rows[i]); 109 | } 110 | } 111 | // removes sort indicators for current column being sorted 112 | function removeSortIndicators() { 113 | var col = getNthColumn(currentSort.index), 114 | cls = col.className; 115 | 116 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 117 | col.className = cls; 118 | } 119 | // adds sort indicators for current column being sorted 120 | function addSortIndicators() { 121 | getNthColumn(currentSort.index).className += currentSort.desc 122 | ? ' sorted-desc' 123 | : ' sorted'; 124 | } 125 | // adds event listeners for all sorter widgets 126 | function enableUI() { 127 | var i, 128 | el, 129 | ithSorter = function ithSorter(i) { 130 | var col = cols[i]; 131 | 132 | return function() { 133 | var desc = col.defaultDescSort; 134 | 135 | if (currentSort.index === i) { 136 | desc = !currentSort.desc; 137 | } 138 | sortByIndex(i, desc); 139 | removeSortIndicators(); 140 | currentSort.index = i; 141 | currentSort.desc = desc; 142 | addSortIndicators(); 143 | }; 144 | }; 145 | for (i = 0; i < cols.length; i += 1) { 146 | if (cols[i].sortable) { 147 | // add the click event handler on the th so users 148 | // dont have to click on those tiny arrows 149 | el = getNthColumn(i).querySelector('.sorter').parentElement; 150 | if (el.addEventListener) { 151 | el.addEventListener('click', ithSorter(i)); 152 | } else { 153 | el.attachEvent('onclick', ithSorter(i)); 154 | } 155 | } 156 | } 157 | } 158 | // adds sorting functionality to the UI 159 | return function() { 160 | if (!getTable()) { 161 | return; 162 | } 163 | cols = loadColumns(); 164 | loadData(); 165 | addSortIndicators(); 166 | enableUI(); 167 | }; 168 | })(); 169 | 170 | window.addEventListener('load', addSorting); 171 | -------------------------------------------------------------------------------- /functions/abs.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import { IComplex, IComplexConstructor } from '../internal/complex'; 3 | import mask from '../internal/mask'; 4 | import getAbs from '../methods/getAbs'; 5 | 6 | export default function abs(Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | const zAbs = typeof z === 'number' 8 | ? absImpl(z, i) 9 | : getAbs(z); 10 | 11 | return new Complex(zAbs, 0, zAbs, 0, mask.HAS_ALL); 12 | } 13 | -------------------------------------------------------------------------------- /functions/acos.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import mul from '../methods/mul'; 4 | import sub from '../methods/sub'; 5 | import from from './from'; 6 | import log from './log'; 7 | import sqrt from './sqrt'; 8 | import square from './square'; 9 | 10 | export default function acos (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 11 | const ONE = from(Complex, 1); 12 | const I = from(Complex, 0, 1); 13 | const PI_2 = from(Complex, 0.5 * Math.PI); 14 | 15 | const mul1 = mul(Complex, I, z, i); 16 | const square1 = square(Complex, z, i); 17 | const sub1 = sub(Complex, ONE, square1); 18 | const sqrt1 = sqrt(Complex, sub1); 19 | const add1 = add(Complex, mul1, sqrt1); 20 | const log1 = log(Complex, add1); 21 | const mul2 = mul(Complex, I, log1); 22 | 23 | return add(Complex, PI_2, mul2); 24 | } 25 | -------------------------------------------------------------------------------- /functions/acosh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import mul from '../methods/mul'; 4 | import from from './from'; 5 | import log from './log'; 6 | import sqrt from './sqrt'; 7 | 8 | export default function acosh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | const ONE = from(Complex, 1); 10 | const NEG_ONE = from(Complex, -1); 11 | 12 | const add1 = add(Complex, NEG_ONE, z, i); 13 | const sqrt1 = sqrt(Complex, add1); 14 | const add2 = add(Complex, ONE, z, i); 15 | const sqrt2 = sqrt(Complex, add2); 16 | const mul1 = mul(Complex, sqrt1, sqrt2); 17 | const add3 = add(Complex, mul1, z, i); 18 | 19 | return log(Complex, add3); 20 | } 21 | -------------------------------------------------------------------------------- /functions/arg.ts: -------------------------------------------------------------------------------- 1 | import argImpl from '../internal/argImpl'; 2 | import { IComplex, IComplexConstructor } from '../internal/complex'; 3 | import mask from '../internal/mask'; 4 | import getArg from '../methods/getArg'; 5 | 6 | export default function arg(Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | const zArg = typeof z === 'number' 8 | ? argImpl(z, i) 9 | : getArg(z); 10 | 11 | return new Complex( 12 | zArg, 13 | 0, 14 | Math.abs(zArg), 15 | zArg < 0 ? Math.PI : 0, 16 | mask.HAS_ALL 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /functions/asin.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import mul from '../methods/mul'; 4 | import sub from '../methods/sub'; 5 | import from from './from'; 6 | import log from './log'; 7 | import sqrt from './sqrt'; 8 | import square from './square'; 9 | 10 | export default function asin (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 11 | const ONE = from(Complex, 1); 12 | const I = from(Complex, 0, 1); 13 | const NEG_I = from(Complex, 0, -1); 14 | 15 | const mul1 = mul(Complex, I, z, i); 16 | const square1 = square(Complex, z, i); 17 | const sub1 = sub(Complex, ONE, square1); 18 | const sqrt1 = sqrt(Complex, sub1); 19 | const add1 = add(Complex, mul1, sqrt1); 20 | const log1 = log(Complex, add1); 21 | 22 | return mul(Complex, NEG_I, log1); 23 | } 24 | -------------------------------------------------------------------------------- /functions/asinh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import from from './from'; 4 | import log from './log'; 5 | import sqrt from './sqrt'; 6 | import square from './square'; 7 | 8 | export default function asinh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | const ONE = from(Complex, 1); 10 | 11 | const square1 = square(Complex, z, i); 12 | const add1 = add(Complex, ONE, square1); 13 | const sqrt1 = sqrt(Complex, add1); 14 | const add2 = add(Complex, sqrt1, z, i); 15 | 16 | return log(Complex, add2); 17 | } 18 | -------------------------------------------------------------------------------- /functions/atan.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import mul from '../methods/mul'; 4 | import sub from '../methods/sub'; 5 | import from from './from'; 6 | import log from './log'; 7 | 8 | export default function atan (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | const ONE = from(Complex, 1); 10 | const I = from(Complex, 0, 1); 11 | const I_2 = from(Complex, 0, 0.5); 12 | 13 | const mul1 = mul(Complex, I, z, i); 14 | const sub1 = sub(Complex, ONE, mul1); 15 | const log1 = log(Complex, sub1); 16 | const add1 = add(Complex, ONE, mul1); 17 | const log2 = log(Complex, add1); 18 | const sub2 = sub(Complex, log1, log2); 19 | 20 | return mul(Complex, I_2, sub2); 21 | } 22 | -------------------------------------------------------------------------------- /functions/atanh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import add from '../methods/add'; 3 | import mul from '../methods/mul'; 4 | import sub from '../methods/sub'; 5 | import from from './from'; 6 | import log from './log'; 7 | 8 | export default function atanh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | const ONE = from(Complex, 1); 10 | const ONE_2 = from(Complex, 0.5); 11 | 12 | const add1 = add(Complex, ONE, z, i); 13 | const log1 = log(Complex, add1); 14 | const sub1 = sub(Complex, ONE, z, i); 15 | const log2 = log(Complex, sub1); 16 | const sub2 = sub(Complex, log1, log2); 17 | 18 | return mul(Complex, ONE_2, sub2); 19 | } 20 | -------------------------------------------------------------------------------- /functions/cbrt.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import argImpl from '../internal/argImpl'; 3 | import { IComplex, IComplexConstructor } from '../internal/complex'; 4 | import mask from '../internal/mask'; 5 | import getAbs from '../methods/getAbs'; 6 | import getArg from '../methods/getArg'; 7 | 8 | export default function cbrt (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | let zAbs: number; 10 | let zArg: number; 11 | 12 | if (typeof z === 'number') { 13 | zAbs = absImpl(z, i); 14 | zArg = argImpl(z, i); 15 | } else { 16 | zAbs = getAbs(z); 17 | zArg = getArg(z); 18 | } 19 | 20 | return new Complex( 21 | NaN, 22 | NaN, 23 | Math.pow(zAbs, 1 / 3), 24 | zArg / 3, 25 | mask.HAS_POLAR 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /functions/ceil.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function ceil (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex(Math.ceil(zReal), Math.ceil(zImag), NaN, NaN, mask.HAS_CARTESIAN); 19 | } 20 | -------------------------------------------------------------------------------- /functions/conj.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function conj (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 5 | let zReal: number 6 | let zImag: number 7 | let zAbs: number 8 | let zArg: number 9 | let zMask: mask; 10 | 11 | if (typeof z === 'number') { 12 | zReal = z; 13 | zImag = i; 14 | zAbs = NaN; 15 | zArg = NaN; 16 | zMask = mask.HAS_CARTESIAN; 17 | } else { 18 | zReal = z._real; 19 | zImag = z._imag; 20 | zAbs = z._abs; 21 | zArg = z._arg; 22 | zMask = z._mask; 23 | } 24 | 25 | return new Complex(zReal, -zImag, zAbs, -zArg, zMask); 26 | } 27 | -------------------------------------------------------------------------------- /functions/cos.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function cos (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zCos = Math.cos(zReal); 20 | 21 | return new Complex( 22 | zCos, 23 | 0, 24 | Math.abs(zCos), 25 | zCos < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zCos = Math.cosh(zImag); 32 | 33 | return new Complex( 34 | zCos, 35 | 0, 36 | Math.abs(zCos), 37 | zCos < 0 ? Math.PI : 0, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | return new Complex( 43 | Math.cos(zReal) * Math.cosh(zImag), 44 | Math.sin(zReal) * Math.sinh(zImag), 45 | NaN, 46 | NaN, 47 | mask.HAS_CARTESIAN 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /functions/cosh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function cosh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zCosh = Math.cosh(zReal); 20 | 21 | return new Complex( 22 | zCosh, 23 | 0, 24 | Math.abs(zCosh), 25 | zCosh < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zCosh = Math.cos(zImag); 32 | 33 | return new Complex( 34 | zCosh, 35 | 0, 36 | Math.abs(zCosh), 37 | zCosh < 0 ? Math.PI : 0, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | return new Complex( 43 | Math.cosh(zReal) * Math.cos(zImag), 44 | Math.sinh(zReal) * Math.sin(zImag), 45 | NaN, 46 | NaN, 47 | mask.HAS_CARTESIAN 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /functions/cube.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function cube (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 5 | let zReal: number; 6 | let zImag: number; 7 | let zAbs: number; 8 | let zArg: number; 9 | let zMask: mask; 10 | 11 | if (typeof z === 'number') { 12 | zReal = z; 13 | zImag = i; 14 | zAbs = NaN; 15 | zArg = NaN; 16 | zMask = mask.HAS_CARTESIAN; 17 | } else { 18 | zReal = z._real; 19 | zImag = z._imag; 20 | zAbs = z._abs; 21 | zArg = z._arg; 22 | zMask = z._mask; 23 | } 24 | 25 | if ((zMask & mask.HAS_CARTESIAN) !== mask.HAS_CARTESIAN) { 26 | return new Complex(NaN, NaN, zAbs * zAbs * zAbs, 3 * zArg, mask.HAS_POLAR); 27 | } 28 | 29 | const real2 = zReal * zReal; 30 | const imag2 = zImag * zImag; 31 | 32 | return new Complex( 33 | (real2 - 3 * imag2) * zReal, 34 | (3 * real2 - imag2) * zImag, 35 | zAbs * zAbs * zAbs, 36 | 3 * zArg, 37 | zMask 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /functions/exp.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function exp (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex( 19 | NaN, 20 | NaN, 21 | Math.exp(zReal), 22 | zImag, 23 | mask.HAS_POLAR 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /functions/floor.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function floor (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex(Math.floor(zReal), Math.floor(zImag), NaN, NaN, mask.HAS_CARTESIAN); 19 | } 20 | -------------------------------------------------------------------------------- /functions/from.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function from (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 5 | let zReal: number; 6 | let zImag: number; 7 | let zAbs: number; 8 | let zArg: number; 9 | let zMask: mask; 10 | 11 | if (typeof z === 'number') { 12 | zReal = z; 13 | zImag = i; 14 | zAbs = NaN; 15 | zArg = NaN; 16 | zMask = mask.HAS_CARTESIAN; 17 | } else { 18 | // to prevent null values from entering into arithmetic operations 19 | // e.g. Complex.from(JSON.parse(text)) 20 | zReal = z._real ?? NaN; 21 | zImag = z._imag ?? NaN; 22 | zAbs = z._abs ?? NaN; 23 | zArg = z._arg ?? NaN; 24 | zMask = z._mask; 25 | } 26 | 27 | return new Complex(zReal, zImag, zAbs, zArg, zMask); 28 | } 29 | -------------------------------------------------------------------------------- /functions/imag.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import imagImpl from '../internal/imagImpl'; 3 | import mask from '../internal/mask'; 4 | import getImag from '../methods/getImag'; 5 | 6 | export default function imag(Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | const zImag = typeof z === 'number' 8 | ? imagImpl(z, i) 9 | : getImag(z); 10 | 11 | return new Complex( 12 | zImag, 13 | 0, 14 | Math.abs(zImag), 15 | zImag < 0 ? Math.PI : 0, 16 | mask.HAS_ALL 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /functions/log.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import argImpl from '../internal/argImpl'; 3 | import { IComplex, IComplexConstructor } from '../internal/complex'; 4 | import mask from '../internal/mask'; 5 | import getAbs from '../methods/getAbs'; 6 | import getArg from '../methods/getArg'; 7 | 8 | export default function log (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | let zAbs: number; 10 | let zArg: number; 11 | 12 | if (typeof z === 'number') { 13 | zAbs = absImpl(z, i); 14 | zArg = argImpl(z, i); 15 | } else { 16 | zAbs = getAbs(z); 17 | zArg = getArg(z); 18 | } 19 | 20 | return new Complex( 21 | Math.log(zAbs), 22 | zArg, 23 | NaN, 24 | NaN, 25 | mask.HAS_CARTESIAN 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /functions/neg.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function neg (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 5 | let zReal: number; 6 | let zImag: number; 7 | let zAbs: number; 8 | let zArg: number; 9 | let zMask: mask; 10 | 11 | if (typeof z === 'number') { 12 | zReal = z; 13 | zImag = i; 14 | zAbs = NaN; 15 | zArg = NaN; 16 | zMask = mask.HAS_CARTESIAN; 17 | } else { 18 | zReal = z._real; 19 | zImag = z._imag; 20 | zAbs = z._abs; 21 | zArg = z._arg; 22 | zMask = z._mask; 23 | } 24 | 25 | return new Complex(-zReal, -zImag, zAbs, zArg + Math.PI, zMask); 26 | } 27 | -------------------------------------------------------------------------------- /functions/not.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function not (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex(~zReal, ~zImag, NaN, NaN, mask.HAS_CARTESIAN); 19 | } 20 | -------------------------------------------------------------------------------- /functions/polar.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function polar (Complex: IComplexConstructor, abs: number, arg = 0): T { 5 | let zAbs: number; 6 | let zArg: number; 7 | 8 | if (abs < 0) { 9 | zAbs = -abs; 10 | zArg = arg + Math.PI; 11 | } else { 12 | zAbs = abs; 13 | zArg = arg; 14 | } 15 | 16 | return new Complex(NaN, NaN, zAbs, zArg, mask.HAS_POLAR); 17 | } 18 | -------------------------------------------------------------------------------- /functions/random.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function random (Complex: IComplexConstructor): T { 5 | return new Complex(Math.random(), Math.random(), NaN, NaN, mask.HAS_CARTESIAN); 6 | } 7 | -------------------------------------------------------------------------------- /functions/real.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import realImpl from '../internal/realImpl'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function real(Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | const zReal = typeof z === 'number' 8 | ? realImpl(z, i) 9 | : getReal(z); 10 | 11 | return new Complex( 12 | zReal, 13 | 0, 14 | Math.abs(zReal), 15 | zReal < 0 ? Math.PI : 0, 16 | mask.HAS_ALL 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /functions/round.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function round (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex(Math.round(zReal), Math.round(zImag), NaN, NaN, mask.HAS_CARTESIAN); 19 | } 20 | -------------------------------------------------------------------------------- /functions/sign.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import argImpl from '../internal/argImpl'; 3 | import { IComplex, IComplexConstructor } from '../internal/complex'; 4 | import mask from '../internal/mask'; 5 | import getAbs from '../methods/getAbs'; 6 | import getArg from '../methods/getArg'; 7 | 8 | export default function sign (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | let zReal: number; 10 | let zImag: number 11 | let zAbs: number; 12 | let zArg: number; 13 | let zMask: mask; 14 | 15 | if (typeof z === 'number') { 16 | zReal = z; 17 | zImag = i; 18 | zAbs = absImpl(z, i); 19 | zArg = NaN; 20 | zMask = mask.HAS_CARTESIAN | mask.HAS_ABS; 21 | } else { 22 | zReal = z._real; 23 | zImag = z._imag; 24 | zAbs = getAbs(z); 25 | zArg = z._arg; 26 | zMask = z._mask; 27 | } 28 | 29 | if (zAbs === 0) { 30 | return new Complex(0, 0, 0, 0, mask.HAS_ALL); 31 | } 32 | 33 | if (zAbs !== Infinity) { 34 | return new Complex(zReal / zAbs, zImag / zAbs, 1, zArg, zMask | mask.HAS_ABS); 35 | } 36 | 37 | const zSignArg = typeof z === 'number' 38 | ? argImpl(zReal, zImag) 39 | : getArg(z); 40 | 41 | return new Complex(NaN, NaN, 1, zSignArg, mask.HAS_POLAR); 42 | } 43 | -------------------------------------------------------------------------------- /functions/sin.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function sin (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zSin = Math.sin(zReal); 20 | 21 | return new Complex( 22 | zSin, 23 | 0, 24 | Math.abs(zSin), 25 | zSin < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zSin = Math.sinh(zImag); 32 | 33 | return new Complex( 34 | 0, 35 | zSin, 36 | Math.abs(zSin), 37 | (zSin < 0 ? -0.5 : 0.5) * Math.PI, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | return new Complex( 43 | Math.sin(zReal) * Math.cosh(zImag), 44 | Math.cos(zReal) * Math.sinh(zImag), 45 | NaN, 46 | NaN, 47 | mask.HAS_CARTESIAN 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /functions/sinh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function sinh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zSinh = Math.sinh(zReal); 20 | 21 | return new Complex( 22 | zSinh, 23 | 0, 24 | Math.abs(zSinh), 25 | zSinh < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zSinh = Math.sin(zImag); 32 | 33 | return new Complex( 34 | 0, 35 | zSinh, 36 | Math.abs(zSinh), 37 | (zSinh < 0 ? -0.5 : 0.5) * Math.PI, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | return new Complex( 43 | Math.sinh(zReal) * Math.cos(zImag), 44 | Math.cosh(zReal) * Math.sin(zImag), 45 | NaN, 46 | NaN, 47 | mask.HAS_CARTESIAN 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /functions/sqrt.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import argImpl from '../internal/argImpl'; 3 | import { IComplex, IComplexConstructor } from '../internal/complex'; 4 | import mask from '../internal/mask'; 5 | import getAbs from '../methods/getAbs'; 6 | import getArg from '../methods/getArg'; 7 | 8 | export default function sqrt (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 9 | let zAbs: number; 10 | let zArg: number; 11 | 12 | if (typeof z === 'number') { 13 | zAbs = absImpl(z, i); 14 | zArg = argImpl(z, i); 15 | } else { 16 | zAbs = getAbs(z); 17 | zArg = getArg(z); 18 | } 19 | 20 | return new Complex( 21 | NaN, 22 | NaN, 23 | Math.sqrt(zAbs), 24 | 0.5 * zArg, 25 | mask.HAS_POLAR 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /functions/square.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | 4 | export default function square (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 5 | let zReal: number; 6 | let zImag: number; 7 | let zAbs: number; 8 | let zArg: number; 9 | let zMask: mask; 10 | 11 | if (typeof z === 'number') { 12 | zReal = z; 13 | zImag = i; 14 | zAbs = NaN; 15 | zArg = NaN; 16 | zMask = mask.HAS_CARTESIAN; 17 | } else { 18 | zReal = z._real; 19 | zImag = z._imag; 20 | zAbs = z._abs; 21 | zArg = z._arg; 22 | zMask = z._mask; 23 | } 24 | 25 | if ((zMask & mask.HAS_CARTESIAN) !== mask.HAS_CARTESIAN) { 26 | return new Complex(NaN, NaN, zAbs * zAbs, 2 * zArg, mask.HAS_POLAR); 27 | } 28 | 29 | const real2 = zReal * zReal; 30 | const imag2 = zImag * zImag; 31 | 32 | return new Complex( 33 | real2 - imag2, 34 | 2 * zReal * zImag, 35 | real2 + imag2, 36 | 2 * zArg, 37 | zMask | mask.HAS_ABS 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /functions/tan.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function tan (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zTan = Math.sin(2 * zReal) / (Math.cos(2 * zReal) + 1); 20 | 21 | return new Complex( 22 | zTan, 23 | 0, 24 | Math.abs(zTan), 25 | zTan < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zTan = Math.sinh(2 * zImag) / (1 + Math.cosh(2 * zImag)); 32 | 33 | return new Complex( 34 | 0, 35 | zTan, 36 | Math.abs(zTan), 37 | (zTan < 0 ? -0.5 : 0.5) * Math.PI, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | const zTanDenom = Math.cos(2 * zReal) + Math.cosh(2 * zImag); 43 | 44 | return new Complex( 45 | Math.sin(2 * zReal) / zTanDenom, 46 | Math.sinh(2 * zImag) / zTanDenom, 47 | NaN, 48 | NaN, 49 | mask.HAS_CARTESIAN 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /functions/tanh.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function tanh (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | if (zImag === 0) { 19 | const zTanh = Math.sinh(2 * zReal) / (Math.cosh(2 * zReal) + 1); 20 | 21 | return new Complex( 22 | zTanh, 23 | 0, 24 | Math.abs(zTanh), 25 | zTanh < 0 ? Math.PI : 0, 26 | mask.HAS_ALL 27 | ); 28 | } 29 | 30 | if (zReal === 0) { 31 | const zTanh = Math.sin(2 * zImag) / (1 + Math.cos(2 * zImag)); 32 | 33 | return new Complex( 34 | 0, 35 | zTanh, 36 | Math.abs(zTanh), 37 | (zTanh < 0 ? -0.5 : 0.5) * Math.PI, 38 | mask.HAS_ALL 39 | ); 40 | } 41 | 42 | const zTanhDenom = Math.cosh(2 * zReal) + Math.cos(2 * zImag); 43 | 44 | return new Complex( 45 | Math.sinh(2 * zReal) / zTanhDenom, 46 | Math.sin(2 * zImag) / zTanhDenom, 47 | NaN, 48 | NaN, 49 | mask.HAS_CARTESIAN 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /functions/trunc.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from '../methods/getImag'; 4 | import getReal from '../methods/getReal'; 5 | 6 | export default function trunc (Complex: IComplexConstructor, z: IComplex | number, i = 0): T { 7 | let zReal: number; 8 | let zImag: number; 9 | 10 | if (typeof z === 'number') { 11 | zReal = z; 12 | zImag = i; 13 | } else { 14 | zReal = getReal(z); 15 | zImag = getImag(z); 16 | } 17 | 18 | return new Complex(Math.trunc(zReal), Math.trunc(zImag), NaN, NaN, mask.HAS_CARTESIAN); 19 | } 20 | -------------------------------------------------------------------------------- /internal/absImpl.ts: -------------------------------------------------------------------------------- 1 | export default function absImpl (real: number, imag: number): number { 2 | return ( 3 | // if z is real, abs = |real| 4 | imag === 0 ? Math.abs(real) 5 | // if z is imag, abs = |imag| 6 | : real === 0 ? Math.abs(imag) 7 | // else abs = |z| 8 | : Math.hypot(real, imag) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /internal/argImpl.ts: -------------------------------------------------------------------------------- 1 | export default function argImpl (real: number, imag: number): number { 2 | return ( 3 | // if z is real, if z is negative, arg = pi, else arg = 0 4 | imag === 0 ? (real < 0 ? Math.PI : 0) 5 | // if z is imag, arg = sign(imag) * pi / 2 6 | : real === 0 ? (imag < 0 ? -0.5 : 0.5) * Math.PI 7 | // else arg = atan(imag / real) 8 | : Math.atan2(imag, real) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /internal/complex.ts: -------------------------------------------------------------------------------- 1 | import mask from './mask'; 2 | 3 | export interface IComplex { 4 | _real: number; 5 | _imag: number; 6 | _arg: number; 7 | _abs: number; 8 | _mask: mask; 9 | } 10 | 11 | export type IComplexConstructor = new (real: number, imag: number, abs: number, arg: number, mask: mask) => T; 12 | -------------------------------------------------------------------------------- /internal/imagImpl.ts: -------------------------------------------------------------------------------- 1 | export default function imagImpl (abs: number, arg: number): number { 2 | return ( 3 | // if z is real, imag = 0 4 | arg === 0 || arg === Math.PI ? 0 5 | // else imag = abs * sin(arg) 6 | : abs * Math.sin(arg) 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /internal/mask.ts: -------------------------------------------------------------------------------- 1 | // @internal 2 | const enum mask { 3 | HAS_NONE = 0, 4 | HAS_REAL = 1, 5 | HAS_IMAG = HAS_REAL << 1, 6 | HAS_ABS = HAS_IMAG << 1, 7 | HAS_ARG = HAS_ABS << 1, 8 | HAS_CARTESIAN = HAS_REAL | HAS_IMAG, 9 | HAS_POLAR = HAS_ABS | HAS_ARG, 10 | HAS_ALL = HAS_CARTESIAN | HAS_POLAR 11 | } 12 | 13 | export default mask; 14 | -------------------------------------------------------------------------------- /internal/realImpl.ts: -------------------------------------------------------------------------------- 1 | export default function realImpl (abs: number, arg: number): number { 2 | return ( 3 | // if z is positive, real = abs 4 | arg === 0 ? abs 5 | // if z is negative, real = -abs 6 | : arg === Math.PI ? -abs 7 | // else real = abs * cos(arg) 8 | : abs * Math.cos(arg) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | collectCoverage: true, 5 | collectCoverageFrom: [ 6 | '**/*.ts', 7 | '!compiler/grammar.ts', 8 | '!docs/**', 9 | '!dst/**', 10 | '!**/node_modules/**' 11 | ], 12 | coverageDirectory: 'docs' 13 | }; 14 | -------------------------------------------------------------------------------- /methods/add.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function add (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex(lhsReal + rhsReal, lhsImag + rhsImag, NaN, NaN, mask.HAS_CARTESIAN); 22 | } 23 | -------------------------------------------------------------------------------- /methods/and.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function and (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex(lhsReal & rhsReal, lhsImag & rhsImag, NaN, NaN, mask.HAS_CARTESIAN); 22 | } 23 | -------------------------------------------------------------------------------- /methods/div.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getAbs from './getAbs'; 4 | import getArg from './getArg'; 5 | import getImag from './getImag'; 6 | import getReal from './getReal'; 7 | 8 | export default function div (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 9 | const rhs = typeof r === 'number' 10 | ? new Complex(r, i, NaN, NaN, mask.HAS_CARTESIAN) 11 | : r; 12 | 13 | const _mask = lhs._mask & rhs._mask; 14 | let rhsAbs2: number; 15 | 16 | switch (_mask) { 17 | case mask.HAS_ALL: 18 | case mask.HAS_CARTESIAN | mask.HAS_ABS: 19 | rhsAbs2 = rhs._abs * rhs._abs; 20 | return new Complex( 21 | (lhs._real * rhs._real + lhs._imag * rhs._imag) / rhsAbs2, 22 | (lhs._imag * rhs._real - lhs._real * rhs._imag) / rhsAbs2, 23 | lhs._abs / rhs._abs, 24 | lhs._arg - rhs._arg, 25 | _mask 26 | ); 27 | case mask.HAS_CARTESIAN | mask.HAS_ARG: 28 | rhsAbs2 = rhs._real * rhs._real + rhs._imag * rhs._imag; 29 | return new Complex( 30 | (lhs._real * rhs._real + lhs._imag * rhs._imag) / rhsAbs2, 31 | (lhs._imag * rhs._real - lhs._real * rhs._imag) / rhsAbs2, 32 | NaN, 33 | lhs._arg - rhs._arg, 34 | _mask 35 | ); 36 | case mask.HAS_CARTESIAN: 37 | case mask.HAS_REAL: 38 | case mask.HAS_IMAG: 39 | rhsAbs2 = getReal(rhs) * rhs._real + getImag(rhs) * rhs._imag; 40 | return new Complex( 41 | (getReal(lhs) * rhs._real + getImag(lhs) * rhs._imag) / rhsAbs2, 42 | (lhs._imag * rhs._real - lhs._real * rhs._imag) / rhsAbs2, 43 | NaN, 44 | NaN, 45 | mask.HAS_CARTESIAN 46 | ); 47 | default: 48 | return new Complex( 49 | NaN, 50 | NaN, 51 | getAbs(lhs) / getAbs(rhs), 52 | getArg(lhs) - getArg(rhs), 53 | mask.HAS_POLAR 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /methods/equals.ts: -------------------------------------------------------------------------------- 1 | import { IComplex } from '../internal/complex'; 2 | import getImag from './getImag'; 3 | import getReal from './getReal'; 4 | 5 | export default function equals (lhs: IComplex, r: IComplex | number, i = 0): boolean { 6 | let rhsReal: number; 7 | let rhsImag: number; 8 | 9 | if (typeof r === 'number') { 10 | rhsReal = r; 11 | rhsImag = i; 12 | } else { 13 | rhsReal = getReal(r); 14 | rhsImag = getImag(r); 15 | } 16 | 17 | const lhsReal = getReal(lhs); 18 | const lhsImag = getImag(lhs); 19 | 20 | return lhsReal === rhsReal && lhsImag === rhsImag; 21 | } 22 | -------------------------------------------------------------------------------- /methods/getAbs.ts: -------------------------------------------------------------------------------- 1 | import absImpl from '../internal/absImpl'; 2 | import { IComplex } from '../internal/complex'; 3 | import mask from '../internal/mask'; 4 | 5 | export default function getAbs (z: IComplex): number { 6 | if (!(z._mask & mask.HAS_ABS)) { 7 | z._abs = absImpl(z._real, z._imag); 8 | z._mask |= mask.HAS_ABS; 9 | } 10 | 11 | return z._abs; 12 | } 13 | -------------------------------------------------------------------------------- /methods/getArg.ts: -------------------------------------------------------------------------------- 1 | import argImpl from '../internal/argImpl'; 2 | import { IComplex } from '../internal/complex'; 3 | import mask from '../internal/mask'; 4 | 5 | export default function getArg (z: IComplex): number { 6 | if (!(z._mask & mask.HAS_ARG)) { 7 | z._arg = argImpl(z._real, z._imag); 8 | z._mask |= mask.HAS_ARG; 9 | } 10 | 11 | return z._arg; 12 | } 13 | -------------------------------------------------------------------------------- /methods/getImag.ts: -------------------------------------------------------------------------------- 1 | import { IComplex } from '../internal/complex'; 2 | import imagImpl from '../internal/imagImpl'; 3 | import mask from '../internal/mask'; 4 | 5 | export default function getImag (z: IComplex): number { 6 | if (!(z._mask & mask.HAS_IMAG)) { 7 | z._imag = imagImpl(z._abs, z._arg); 8 | z._mask |= mask.HAS_IMAG; 9 | } 10 | 11 | return z._imag; 12 | } 13 | -------------------------------------------------------------------------------- /methods/getReal.ts: -------------------------------------------------------------------------------- 1 | import { IComplex } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import realImpl from '../internal/realImpl'; 4 | 5 | export default function getReal (z: IComplex): number { 6 | if (!(z._mask & mask.HAS_REAL)) { 7 | z._real = realImpl(z._abs, z._arg); 8 | z._mask |= mask.HAS_REAL; 9 | } 10 | 11 | return z._real; 12 | } 13 | -------------------------------------------------------------------------------- /methods/mod.ts: -------------------------------------------------------------------------------- 1 | import trunc from '../functions/trunc'; 2 | import { IComplex, IComplexConstructor } from '../internal/complex'; 3 | import div from './div'; 4 | import mul from './mul'; 5 | import sub from './sub'; 6 | 7 | export default function mod (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 8 | // lhs % rhs = lhs - (trunc(lhs / rhs) * rhs) 9 | const q = div(Complex, lhs, r, i); 10 | const p = mul(Complex, trunc(Complex, q), r, i); 11 | 12 | return sub(Complex, lhs, p); 13 | } 14 | -------------------------------------------------------------------------------- /methods/mul.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getAbs from './getAbs'; 4 | import getArg from './getArg'; 5 | import getImag from './getImag'; 6 | import getReal from './getReal'; 7 | 8 | export default function mul (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 9 | const rhs = typeof r === 'number' 10 | ? new Complex(r, i, NaN, NaN, mask.HAS_CARTESIAN) 11 | : r; 12 | 13 | const _mask = lhs._mask & rhs._mask; 14 | 15 | switch (_mask) { 16 | case mask.HAS_ALL: 17 | case mask.HAS_CARTESIAN | mask.HAS_ABS: 18 | case mask.HAS_CARTESIAN | mask.HAS_ARG: 19 | case mask.HAS_CARTESIAN: 20 | return new Complex( 21 | lhs._real * rhs._real - lhs._imag * rhs._imag, 22 | lhs._imag * rhs._real + lhs._real * rhs._imag, 23 | lhs._abs * rhs._abs, 24 | lhs._arg + rhs._arg, 25 | _mask 26 | ); 27 | case mask.HAS_REAL: 28 | case mask.HAS_IMAG: 29 | return new Complex( 30 | getReal(lhs) * getReal(rhs) - getImag(lhs) * getImag(rhs), 31 | lhs._imag * rhs._real + lhs._real * rhs._imag, 32 | NaN, 33 | NaN, 34 | mask.HAS_CARTESIAN 35 | ); 36 | default: 37 | return new Complex( 38 | NaN, 39 | NaN, 40 | getAbs(lhs) * getAbs(rhs), 41 | getArg(lhs) + getArg(rhs), 42 | mask.HAS_POLAR 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /methods/or.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function or (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal | rhsReal, 23 | lhsImag | rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /methods/pow.ts: -------------------------------------------------------------------------------- 1 | import cube from '../functions/cube'; 2 | import from from '../functions/from'; 3 | import square from '../functions/square'; 4 | import { IComplex, IComplexConstructor } from '../internal/complex'; 5 | import mask from '../internal/mask'; 6 | import div from './div'; 7 | import getAbs from './getAbs'; 8 | import getArg from './getArg'; 9 | import getImag from './getImag'; 10 | import getReal from './getReal'; 11 | 12 | export default function pow (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 13 | // rhs = c + di 14 | let c: number; 15 | let d: number; 16 | 17 | if (typeof r === 'number') { 18 | c = r; 19 | d = i; 20 | } else { 21 | c = getReal(r); 22 | d = getImag(r); 23 | } 24 | 25 | if (d === 0) { 26 | switch (c) { 27 | case -1: return div(Complex, from(Complex, 1), lhs); 28 | case 0: return from(Complex, 1); 29 | case 1: return from(Complex, lhs); 30 | case 2: return square(Complex, lhs); 31 | case 3: return cube(Complex, lhs); 32 | } 33 | } 34 | 35 | // lhs = m e ** ia 36 | const m = getAbs(lhs); 37 | const a = getArg(lhs); 38 | 39 | // lhs ** rhs === (m ** c * e ** -ad) e ** i(d ln(m) + ac) 40 | // from https://en.wikipedia.org/wiki/Exponentiation#Computing_complex_powers 41 | const abs = Math.pow(m, c) * Math.exp(-a * d); 42 | const arg = d * Math.log(m) + a * c; 43 | 44 | return new Complex(NaN, NaN, abs, arg, mask.HAS_POLAR); 45 | } 46 | -------------------------------------------------------------------------------- /methods/sal.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function sal (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal << rhsReal, 23 | lhsImag << rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /methods/sar.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function sar (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal >> rhsReal, 23 | lhsImag >> rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /methods/shr.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function shr (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal >>> rhsReal, 23 | lhsImag >>> rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /methods/sub.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function sub (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal - rhsReal, 23 | lhsImag - rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /methods/toString.ts: -------------------------------------------------------------------------------- 1 | import { IComplex } from '../internal/complex'; 2 | import getAbs from './getAbs'; 3 | import getArg from './getArg'; 4 | import getImag from './getImag'; 5 | import getReal from './getReal'; 6 | 7 | type Coordinates = 'c' | 'p'; 8 | type Radix = 'X' | 'x' | 'o' | 'b' | ''; 9 | type Specifier = 'r' | 'i' | 'm' | 'a'; 10 | interface IFormat { 11 | minus: boolean; 12 | plus: boolean; 13 | pound: boolean; 14 | precision: number | ''; 15 | radix: Radix; 16 | specifier: Specifier; 17 | width: number; 18 | zero: boolean; 19 | } 20 | 21 | const fmtCoord = /%([cp])/g; 22 | const fmtParts = /%([#0+-]{0,4})(\d{0,2})((?:\.\d{0,2})?)([Xxob]?)([rima])/g; 23 | 24 | export default function toString (z: IComplex, format = '%c'): string { 25 | return format 26 | .replace(fmtCoord, replaceCoord) 27 | .replace(fmtParts, replaceParts(z)); 28 | } 29 | 30 | function replaceCoord (_: string, coord: Coordinates): string { 31 | switch (coord) { 32 | case 'c': return '%r%+i*i'; 33 | case 'p': return '%m*e**(%a*i)'; 34 | } 35 | } 36 | 37 | function replaceParts (z: IComplex): (...args: string[]) => string { 38 | return (_, flag, width, precision, radix, specifier) => { 39 | return stringify(z, { 40 | minus: flag.includes('-'), 41 | plus: flag.includes('+'), 42 | pound: flag.includes('#'), 43 | precision: precision && +precision.slice(1), 44 | radix: radix as Radix, 45 | specifier: specifier as Specifier, 46 | width: +width, 47 | zero: flag.includes('0') 48 | }); 49 | }; 50 | } 51 | 52 | function stringify (z: IComplex, format: IFormat): string { 53 | return width(precision(radix(specifier()))); 54 | 55 | function specifier (): number { 56 | switch (format.specifier) { 57 | case 'r': return getReal(z); 58 | case 'i': return getImag(z); 59 | case 'm': return getAbs(z); 60 | case 'a': return getArg(z); 61 | } 62 | } 63 | 64 | function radix (num: number): string { 65 | switch (format.radix) { 66 | case 'X': return num.toString(16).toUpperCase(); 67 | case 'x': return num.toString(16).toLowerCase(); 68 | case 'o': return num.toString(8); 69 | case 'b': return num.toString(2); 70 | case '': return num.toString(10); 71 | } 72 | } 73 | 74 | function precision (str: string): string { 75 | const target = format.precision; 76 | const index = str.indexOf('.') + 1; 77 | 78 | if (target === '') return str; 79 | 80 | if (index === 0) { 81 | if (target === 0) return str; 82 | 83 | return `${str}.${'0'.repeat(target)}`; 84 | } 85 | 86 | const digits = str.length - index; 87 | const remove = Math.max(digits - target, 0); 88 | const insert = Math.max(target - digits, 0); 89 | 90 | return str.slice(0, str.length - remove) + '0'.repeat(insert); 91 | } 92 | 93 | function width (str: string): string { 94 | if (format.minus) { 95 | return plus(pound(str)).padEnd(format.width, ' '); 96 | } 97 | 98 | if (!format.zero) { 99 | return plus(pound(str)).padStart(format.width, ' '); 100 | } 101 | 102 | if (!str.startsWith('-')) { 103 | return plus(pound(str.padStart(format.width, '0'))); 104 | } 105 | 106 | return plus(pound(`-${str.slice(1).padStart(format.width - 1, '0')}`)); 107 | } 108 | 109 | function plus (str: string) { 110 | if (!format.plus || str.startsWith('-')) { 111 | return str; 112 | } 113 | 114 | return `+${str}`; 115 | } 116 | 117 | function pound (str: string): string { 118 | if (!format.pound || !format.radix) { 119 | return str; 120 | } 121 | 122 | const base = `0${format.radix}`; 123 | 124 | if (!str.startsWith('-')) { 125 | return base + str; 126 | } 127 | 128 | return `-${base + str.slice(1)}`; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /methods/xor.ts: -------------------------------------------------------------------------------- 1 | import { IComplex, IComplexConstructor } from '../internal/complex'; 2 | import mask from '../internal/mask'; 3 | import getImag from './getImag'; 4 | import getReal from './getReal'; 5 | 6 | export default function xor (Complex: IComplexConstructor, lhs: IComplex, r: IComplex | number, i = 0): T { 7 | let rhsReal: number; 8 | let rhsImag: number; 9 | 10 | if (typeof r === 'number') { 11 | rhsReal = r; 12 | rhsImag = i; 13 | } else { 14 | rhsReal = getReal(r); 15 | rhsImag = getImag(r); 16 | } 17 | 18 | const lhsReal = getReal(lhs); 19 | const lhsImag = getImag(lhs); 20 | 21 | return new Complex( 22 | lhsReal ^ rhsReal, 23 | lhsImag ^ rhsImag, 24 | NaN, 25 | NaN, 26 | mask.HAS_CARTESIAN 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "complex-js", 3 | "version": "6.0.3-alpha", 4 | "description": "Complex math for the browser and Node.js", 5 | "main": "dst/complex.js", 6 | "module": "dst/complex.mjs", 7 | "browser": "dst/complex.min.js", 8 | "types": "dst/complex.d.ts", 9 | "repository": "github:patrickroberts/complex-js", 10 | "homepage": "https://patrickroberts.github.io/complex-js/", 11 | "bugs": "https://github.com/patrickroberts/gpcpu/issues", 12 | "author": "Patrick Roberts", 13 | "license": "MIT", 14 | "keywords": [ 15 | "complex", 16 | "math", 17 | "compiler", 18 | "isomorphic" 19 | ], 20 | "scripts": { 21 | "clean": "rimraf docs dst compiler/grammar.ts", 22 | "compile": "nearleyc compiler/grammar.ne -o compiler/grammar.ts", 23 | "lint": "tslint -p . -e compiler/grammar.ts", 24 | "bundle": "rollup -c", 25 | "build": "npm run compile && npm run lint && npm run bundle", 26 | "rebuild": "npm run clean && npm run build", 27 | "docs": "typedoc complex.ts", 28 | "test": "jest", 29 | "prepublishOnly": "npm un moo nearley && npm run rebuild && npm run docs && npm run test" 30 | }, 31 | "engines": { 32 | "node": ">=0.10.0" 33 | }, 34 | "devDependencies": { 35 | "@rollup/plugin-typescript": "^3.0.0", 36 | "@types/jest": "^25.1.3", 37 | "@types/moo": "^0.5.2", 38 | "@types/nearley": "^2.11.1", 39 | "jest": "^25.1.0", 40 | "rimraf": "^3.0.2", 41 | "rollup": "^1.31.1", 42 | "rollup-plugin-dts": "^1.2.1", 43 | "rollup-plugin-peer-deps-external": "^2.2.2", 44 | "rollup-plugin-terser": "^5.2.0", 45 | "ts-jest": "^25.2.1", 46 | "tslib": "^1.10.0", 47 | "tslint": "^5.11.0", 48 | "tslint-config-airbnb": "^5.11.2", 49 | "tslint-config-prettier": "^1.18.0", 50 | "tslint-eslint-rules": "^5.4.0", 51 | "typedoc": "^0.15.8", 52 | "typedoc-plugin-sourcefile-url": "^1.0.4", 53 | "typescript": "^3.7.5" 54 | }, 55 | "peerDependencies": { 56 | "moo": "^0.5.1", 57 | "nearley": "^2.19.1" 58 | }, 59 | "dependencies": {} 60 | } 61 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript'; 2 | import external from 'rollup-plugin-peer-deps-external'; 3 | import dts from 'rollup-plugin-dts'; 4 | import { terser } from 'rollup-plugin-terser'; 5 | import pkg from './package.json'; 6 | 7 | const name = 'Complex'; 8 | const input = 'complex.ts'; 9 | const moo = 'moo'; 10 | const nearley = 'nearley'; 11 | const globals = { moo, nearley }; 12 | 13 | export default [ 14 | { 15 | input, 16 | output: { file: pkg.module, format: 'es' }, 17 | plugins: [external(), typescript()] 18 | }, 19 | { 20 | input, 21 | output: { file: pkg.main, format: 'commonjs', name }, 22 | plugins: [external(), typescript({ target: 'es5' })] 23 | }, 24 | { 25 | input, 26 | output: { file: pkg.browser, format: 'umd', name, globals, sourcemap: true }, 27 | plugins: [external(), typescript({ target: 'es5' }), terser()] 28 | }, 29 | { 30 | input, 31 | output: { file: pkg.types, format: 'es' }, 32 | plugins: [dts()] 33 | } 34 | ]; 35 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "stripInternal": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint:latest", 6 | "tslint-config-airbnb", 7 | "tslint-eslint-rules", 8 | "tslint-config-prettier" 9 | ], 10 | "jsRules": {}, 11 | "rules": { 12 | "array-type": [true, "array"], 13 | "no-bitwise": false, 14 | "no-implicit-dependencies": false, 15 | "no-shadowed-variable": [ 16 | true, 17 | { 18 | "import": false 19 | } 20 | ], 21 | "no-submodule-imports": false, 22 | "variable-name": { 23 | "options": [ 24 | "allow-leading-underscore", 25 | "allow-pascal-case" 26 | ] 27 | } 28 | }, 29 | "rulesDirectory": [ 30 | "node_modules/tslint-eslint-rules/dist/rules" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "out": "docs", 3 | "theme": "minimal", 4 | "mode": "file", 5 | "excludeExternals": true, 6 | "excludeNotExported": true, 7 | "sourcefile-url-prefix": "https://github.com/patrickroberts/complex-js/blob/master/" 8 | } 9 | --------------------------------------------------------------------------------