Chris@25
|
1 'use strict';
|
Chris@25
|
2
|
Chris@25
|
3 !function(exports, undefined) {
|
Chris@25
|
4
|
Chris@25
|
5 var
|
Chris@25
|
6 // If the typed array is unspecified, use this.
|
Chris@25
|
7 DefaultArrayType = Float32Array,
|
Chris@25
|
8 // Simple math functions we need.
|
Chris@25
|
9 sqrt = Math.sqrt,
|
Chris@25
|
10 sqr = function(number) {return Math.pow(number, 2)},
|
Chris@25
|
11 // Internal convenience copies of the exported functions
|
Chris@25
|
12 isComplexArray,
|
Chris@25
|
13 ComplexArray
|
Chris@25
|
14
|
Chris@25
|
15 exports.isComplexArray = isComplexArray = function(obj) {
|
Chris@25
|
16 return obj !== undefined &&
|
Chris@25
|
17 obj.hasOwnProperty !== undefined &&
|
Chris@25
|
18 obj.hasOwnProperty('real') &&
|
Chris@25
|
19 obj.hasOwnProperty('imag')
|
Chris@25
|
20 }
|
Chris@25
|
21
|
Chris@25
|
22 exports.ComplexArray = ComplexArray = function(other, opt_array_type){
|
Chris@25
|
23 if (isComplexArray(other)) {
|
Chris@25
|
24 // Copy constuctor.
|
Chris@25
|
25 this.ArrayType = other.ArrayType
|
Chris@25
|
26 this.real = new this.ArrayType(other.real)
|
Chris@25
|
27 this.imag = new this.ArrayType(other.imag)
|
Chris@25
|
28 } else {
|
Chris@25
|
29 this.ArrayType = opt_array_type || DefaultArrayType
|
Chris@25
|
30 // other can be either an array or a number.
|
Chris@25
|
31 this.real = new this.ArrayType(other)
|
Chris@25
|
32 this.imag = new this.ArrayType(this.real.length)
|
Chris@25
|
33 }
|
Chris@25
|
34
|
Chris@25
|
35 this.length = this.real.length
|
Chris@25
|
36 }
|
Chris@25
|
37
|
Chris@25
|
38 ComplexArray.prototype.toString = function() {
|
Chris@25
|
39 var components = []
|
Chris@25
|
40
|
Chris@25
|
41 this.forEach(function(c_value, i) {
|
Chris@25
|
42 components.push(
|
Chris@25
|
43 '(' +
|
Chris@25
|
44 c_value.real.toFixed(2) + ',' +
|
Chris@25
|
45 c_value.imag.toFixed(2) +
|
Chris@25
|
46 ')'
|
Chris@25
|
47 )
|
Chris@25
|
48 })
|
Chris@25
|
49
|
Chris@25
|
50 return '[' + components.join(',') + ']'
|
Chris@25
|
51 }
|
Chris@25
|
52
|
Chris@25
|
53 // In-place mapper.
|
Chris@25
|
54 ComplexArray.prototype.map = function(mapper) {
|
Chris@25
|
55 var
|
Chris@25
|
56 i,
|
Chris@25
|
57 n = this.length,
|
Chris@25
|
58 // For GC efficiency, pass a single c_value object to the mapper.
|
Chris@25
|
59 c_value = {}
|
Chris@25
|
60
|
Chris@25
|
61 for (i = 0; i < n; i++) {
|
Chris@25
|
62 c_value.real = this.real[i]
|
Chris@25
|
63 c_value.imag = this.imag[i]
|
Chris@25
|
64 mapper(c_value, i, n)
|
Chris@25
|
65 this.real[i] = c_value.real
|
Chris@25
|
66 this.imag[i] = c_value.imag
|
Chris@25
|
67 }
|
Chris@25
|
68
|
Chris@25
|
69 return this
|
Chris@25
|
70 }
|
Chris@25
|
71
|
Chris@25
|
72 ComplexArray.prototype.forEach = function(iterator) {
|
Chris@25
|
73 var
|
Chris@25
|
74 i,
|
Chris@25
|
75 n = this.length,
|
Chris@25
|
76 // For consistency with .map.
|
Chris@25
|
77 c_value = {}
|
Chris@25
|
78
|
Chris@25
|
79 for (i = 0; i < n; i++) {
|
Chris@25
|
80 c_value.real = this.real[i]
|
Chris@25
|
81 c_value.imag = this.imag[i]
|
Chris@25
|
82 iterator(c_value, i, n)
|
Chris@25
|
83 }
|
Chris@25
|
84 }
|
Chris@25
|
85
|
Chris@25
|
86 ComplexArray.prototype.conjugate = function() {
|
Chris@25
|
87 return (new ComplexArray(this)).map(function(value) {
|
Chris@25
|
88 value.imag *= -1
|
Chris@25
|
89 })
|
Chris@25
|
90 }
|
Chris@25
|
91
|
Chris@25
|
92 // Helper so we can make ArrayType objects returned have similar interfaces
|
Chris@25
|
93 // to ComplexArrays.
|
Chris@25
|
94 function iterable(obj) {
|
Chris@25
|
95 if (!obj.forEach)
|
Chris@25
|
96 obj.forEach = function(iterator) {
|
Chris@25
|
97 var i, n = this.length
|
Chris@25
|
98
|
Chris@25
|
99 for (i = 0; i < n; i++)
|
Chris@25
|
100 iterator(this[i], i, n)
|
Chris@25
|
101 }
|
Chris@25
|
102
|
Chris@25
|
103 return obj
|
Chris@25
|
104 }
|
Chris@25
|
105
|
Chris@25
|
106 ComplexArray.prototype.magnitude = function() {
|
Chris@25
|
107 var mags = new this.ArrayType(this.length)
|
Chris@25
|
108
|
Chris@25
|
109 this.forEach(function(value, i) {
|
Chris@25
|
110 mags[i] = sqrt(sqr(value.real) + sqr(value.imag))
|
Chris@25
|
111 })
|
Chris@25
|
112
|
Chris@25
|
113 // ArrayType will not necessarily be iterable: make it so.
|
Chris@25
|
114 return iterable(mags)
|
Chris@25
|
115 }
|
Chris@25
|
116 }(typeof exports === 'undefined' && (this.complex_array = {}) || exports)
|