ziko
Version:
A versatile JavaScript library offering a rich set of Hyperscript Based UI components, advanced mathematical utilities, interactivity ,animations, client side routing and more ...
189 lines (187 loc) • 5.4 kB
JavaScript
// import {sum,prod,deg2rad} from "../utils/index.js";
// Should avoid CD
class Complex{
constructor(a = 0, b = 0) {
if(a instanceof Complex){
this.a=a.a;
this.b=a.b;
}
else if(typeof(a)==="object"){
if(("a" in a && "b" in a)){
this.a = a.a;
this.b = a.b;
}
else if(("a" in a && "z" in a)){
this.a = a.a;
this.b = Math.sqrt((a.z**2)-(a.a**2));
}
else if(("a" in a && "phi" in a)){
this.a = a.a;
this.b = a.a * Math.tan(a.phi);
}
else if(("b" in a && "z" in a)){
this.b = a.b;
this.a = Math.sqrt((a.z**2)-(a.b**2));
}
else if(("b" in a && "phi" in a)){
this.b = b;
this.a = a.b / Math.tan(a.phi);
}
else if(("z" in a && "phi" in a)){
this.a = + a.z * Math.cos(a.phi).toFixed(15);
this.b = + a.z * Math.sin(a.phi).toFixed(15);
}
}
else if(typeof(a)==="number" && typeof(b)==="number"){
this.a = + a.toFixed(32);
this.b = + b.toFixed(32);
}
}
get __mapfun__(){
return true
}
isComplex(){
return true
}
toString(){
let str = "";
if (this.a !== 0)
this.b >= 0
? (str = `${this.a}+${this.b}*i`)
: (str = `${this.a}-${Math.abs(this.b)}*i`);
else
this.b >= 0
? (str = `${this.b}*i`)
: (str = `-${Math.abs(this.b)}*i`);
return str;
}
clone() {
return new Complex(this.a, this.b);
}
get z(){
return Math.hypot(this.a,this.b);
}
get phi(){
return Math.atan2(this.b , this.a);
}
static Zero() {
return new Complex(0, 0);
}
get conj() {
return new Complex(this.a, -this.b);
}
get inv() {
return new Complex(
this.a / Math.hypot(this.a, this.b),
-this.b / Math.hypot(this.a, this.b)
);
}
add(...c) {
for (let i = 0; i < c.length; i++) {
if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
this.a += c[i].a;
this.b += c[i].b;
}
return this;
}
sub(...c) {
for (let i = 0; i < c.length; i++) {
if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
this.a -= c[i].a;
this.b -= c[i].b;
}
return this;
}
mul(...c){
let {z, phi} = this;
for (let i = 0; i < c.length; i++) {
if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
z *= c[i].z;
phi += c[i].z;
}
this.a = z*Math.cos(phi)
this.b = z*Math.sin(phi)
return this;
}
div(...c){
let {z, phi} = this;
for (let i = 0; i < c.length; i++) {
if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
z /= c[i].z;
phi -= c[i].z;
}
this.a = z*Math.cos(phi)
this.b = z*Math.sin(phi)
return this;
}
modulo(...c) {
for (let i = 0; i < c.length; i++) {
if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
this.a %= c[i].a;
this.b %= c[i].b;
}
return this;
}
static fromExpo(z, phi) {
return new Complex(
+(z * cos(phi)).toFixed(13),
+(z * sin(phi)).toFixed(13)
);
}
get expo() {
return [this.z, this.phi];
}
static add(c,...z) {
return c.clone().add(...z);
}
static sub(c,...z) {
return c.clone().sub(...z);
}
static mul(c,...z) {
return c.clone().mul(...z);
}
static div(c,...z) {
return c.clone().div(...z);
}
nthr(n=2){
return complex({z: this.z ** (1/n), phi: this.phi / n});
}
get sqrt(){
return this.nrth(2);
}
get cbrt(){
return this.nrth(3);
}
get log(){
return complex(this.z, this.phi);
}
get cos(){
return complex(
Math.cos(this.a) * Math.cosh(this.b),
Math.sin(this.a) * Math.sinh(this.b)
)
}
get sin(){
return complex(
Math.sin(this.a) * Math.cosh(this.b),
Math.cos(this.a) * Math.sinh(this.b)
)
}
get tan(){
const D=cos(this.a*2)+cosh(this.b*2);
return complex(
Math.sin(2 * this.a) / D,
Math.sinh(2 * this.b) / D
);
}
}
const complex=(a,b)=>{
if((a instanceof Array||ArrayBuffer.isView(a)) && (b instanceof Array||ArrayBuffer.isView(a)))return a.map((n,i)=>complex(a[i],b[i]));
if(a.isMatrix?.() && b.isMatrix?.()){
if((a.shape[0]!==b.shape[0])||(a.shape[1]!==b.shape[1]))return Error(0)
const arr=a.arr.map((n,i)=>complex(a.arr[i],b.arr[i]))
return new a.constructor(a.rows,a.cols,...arr)
}
return new Complex(a,b)
}
export{complex,Complex}