-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathComplex.js
84 lines (76 loc) · 3.43 KB
/
Complex.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Complex.js
// (c) 2009 B. Crowell and M. Khafateh, GPL 2 license
//
// This file provides a constructor, com.lightandmatter.Complex.
//
var com;
if (!com) {com = {};}
if (!com.lightandmatter) {com.lightandmatter = {};}
com.lightandmatter.Complex =
function (x,y) {
var c = {};
c.x = x;
c.y = y;
c.mytype = 'c';
c.clone = function () {return com.lightandmatter.Complex(c.x,c.y); };
c.to_array = function () {return [c.x,c.y];};
c.eq = function (b) {return c.x!==null && c.y!==null && c.x==b.x && c.y==b.y; };
c.add = function (b) {var z = c.clone(); z.x += b.x; z.y += b.y; return z; };
c.sub = function (b) {var z = c.clone(); z.x -= b.x; z.y -= b.y; return z; };
c.sq_abs = function () {return c.x*c.x+c.y*c.y;};
c.abs = function () {return Math.sqrt(c.sq_abs());};
c.arg = function () {return atan2(c.y,c.x);};
c.mul = function (b) { return com.lightandmatter.Complex(c.x*b.x-c.y*b.y,c.x*b.y+c.y*b.x); };
c.inv = function () {
var s = c.sq_abs();
return com.lightandmatter.Complex(c.x/s,-c.y/s); };
c.neg = function () { return com.lightandmatter.Complex(-c.x,-c.y); };
c.div = function (b) { return c.mul(b.inv()); };
c.exp = function () {
var e = Math.exp(c.x);
return com.lightandmatter.Complex(e*Math.cos(c.y),e*Math.sin(c.y));
};
c.arg = function () { return Math.atan2(c.y,c.x); };
c.ln = function () {
return com.lightandmatter.Complex(0.5*Math.log(c.sq_abs()),c.arg());
};
c.force_real = function () {c.y=0;};
c.sq = function () { return c.mul(c); };
c.int_pow = function(p) { // c^p, p is an integer; for internal use only; check for 0^0 before calling this function
// Do these first for efficiency in the case of largish exponents, calling recursively:
if (p===0) {return com.lightandmatter.Complex(1.0,0.0);} // 0^0 not allowed as input
if (p==1) {return c;}
if (p==2) {return c.sq();}
if (c.x===0 && c.y===0) {
if (p>0) {return 0;}
if (p<0) {return NaN;}
}
// From here on, we know that neither c nor p is zero.
if (p<0) {return c.int_pow(-p).inv();}
// If we get to here, p is >=3 and the base c is nonzero.
var m = Math.floor(p/2.0);
var n = p-2*m; // may be 0 or 1
return c.int_pow(m).sq().mul(c.int_pow(n));
};
c.pow = function(b) { // c^b
if (b.x===0 && b.y===0 && c.x===0 && c.y===0) {return NaN;}
if (b.y===0 && b.x==Math.floor(b.x)) { // special-casing for small integer exponents, to avoid loss of precision on expressions like i^3
var p = Math.floor(b.x);
return c.int_pow(p);
}
return c.ln().mul(b).exp();
};
c.sqrt = function() {var z= c.pow(com.lightandmatter.Complex(0.5,0)); if (c.y===0 && c.x<0) {z.x=0;} return z;};
c.floor = function() {return com.lightandmatter.Complex(Math.floor(c.x),Math.floor(c.y));};
c.ceil = function() {return com.lightandmatter.Complex(Math.ceil(c.x),Math.ceil(c.y));};
c.toString = function() {
if (c.y===0) {return com.lightandmatter.Num.convert_to_string(c.x);}
if (c.x===0) {
if (c.y==1) {return 'i';}
if (c.y== -1) {return '-i';}
return com.lightandmatter.Num.convert_to_string(c.y)+' i';
}
return com.lightandmatter.Num.convert_to_string(c.x) + ' + ' + com.lightandmatter.Num.convert_to_string(c.y) + ' i';
};
return c;
};