delta
(1-3 Hz), theta
(4-7 Hz), alpha
(8-12 Hz), beta
(13-30 Hz), or gamma
(31-50 Hz).
+ * While string representations
+ * allow for easier prototyping, the use of a specific band passed as an array is recommended, as band string representations may change in
+ * future updates.
+ * @param {number} [fftSize=Math.pow(2, bci.nextpow2(psd.length))] - Size of the fourier transform used to compute the PSD.
+ * @returns {number} The average power in the frequency band.
+ */
+
+
+function psdBandPower(psd, sampleRate, band) {
+ var fftSize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
+
+ if (fftSize === null) {
+ fftSize = Math.pow(2, nextpow2(psd.length));
+ }
+
+ var bands = {
+ // From Dan Szafir's "Pay Attention!", 2012
+ 'delta': [1, 3],
+ 'theta': [4, 7],
+ 'alpha': [8, 12],
+ 'beta': [13, 30],
+ 'gamma': [31, 50]
+ };
+
+ if (typeof band === 'string' || band instanceof String) {
+ band = bands[band];
+ }
+
+ var startIndex = Math.floor(band[0] / sampleRate * fftSize);
+ var endIndex = Math.min(Math.ceil(band[1] / sampleRate * fftSize), psd.length - 1);
+ var power = 0;
+
+ for (var i = startIndex; i < endIndex + 1; i++) {
+ power += psd[i];
+ }
+
+ return power / (endIndex - startIndex + 1);
+}
+
+module.exports = psdBandPower;
+
+},{"../math/nextpow2.js":25}],8:[function(require,module,exports){
"use strict";
/**
@@ -332,7 +526,121 @@ exports.getPSD = getPSD;
exports.getBandPower = getBandPower;
exports.CSP = require('./csp.js');
-},{"./csp.js":2,"fft.js":44,"mathjs/core":47,"mathjs/lib/function/arithmetic":71,"mathjs/lib/function/matrix":98,"mathjs/lib/function/trigonometry":162,"mathjs/lib/type/bignumber":181,"mathjs/lib/type/matrix":197}],6:[function(require,module,exports){
+},{"./csp.js":3,"fft.js":46,"mathjs/core":49,"mathjs/lib/function/arithmetic":73,"mathjs/lib/function/matrix":100,"mathjs/lib/function/trigonometry":164,"mathjs/lib/type/bignumber":183,"mathjs/lib/type/matrix":199}],9:[function(require,module,exports){
+"use strict";
+
+var psd = require('./psd.js');
+
+var psdBandPower = require('./psdBandPower.js');
+
+var nextpow2 = require('../math/nextpow2.js');
+
+var transpose = require('../math/transpose.js');
+/**
+ * Deprecated, please use bci.bandpower() for output in proper units.
+ *
+ * The functionality of this method has been replaced with the 'bandpower' method.
+ * See the docs for 'bandpower' for more information.
+ *
+ * Computes the average magnitude across each frequency band.
+ *
+ * @deprecated Deprecated since version 1.7.0, will be removed in version 2.0.0
+ *
+ * @memberof module:bcijs
+ * @param {number[]|number[][]} samples - The signal (array of numbers) or a matrix of signals, where rows are samples and columns are signals.
+ * @param {number} sampleRate - The sample rate of the signal.
+ * @param {(Array|string)} bands - The frequency band or array of bands, where a single band is provided as an array [frequencyStart, frequencyStop] or a string delta
(1-3 Hz), theta
(4-7 Hz), alpha
(8-12 Hz), beta
(13-30 Hz), or gamma
(31-50 Hz).delta
(1-3 Hz), theta
(4-7 Hz), alpha
(8-12 Hz), beta
(13-30 Hz), or gamma
(31-50 Hz).
- * While string representations
- * allow for easier prototyping, the use of a specific band passed as an array is recommended, as band string representations may change in
- * future updates.
- * @param {number} [fftSize=Math.pow(2, bci.nextpow2(psd.length))] - Size of the fourier transform used to compute the PSD.
- * @returns {number} The average power in the frequency band.
- */
+ var powers = [];
+ var scaling_factor = 2 / (sample_rate * S);
+ for (var i = 0; i < freqs.length - 1; i += 2) {
+ // magnitude is sqrt(real^2 + imag^2)
+ var magnitude = Math.sqrt(Math.pow(freqs[i], 2) + Math.pow(freqs[i + 1], 2)); // apply scaling
-function psdBandPower(psd, sampleRate, band) {
- var fftSize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
+ var power = scaling_factor * Math.pow(magnitude, 2);
+ powers.push(power);
+ } // Toss values past Nyquist
- if (fftSize === null) {
- fftSize = Math.pow(2, nextpow2(psd.length));
- }
- var bands = {
- // From Dan Szafir's "Pay Attention!", 2012
- 'delta': [1, 3],
- 'theta': [4, 7],
- 'alpha': [8, 12],
- 'beta': [13, 30],
- 'gamma': [31, 50]
- };
+ powers = powers.slice(0, powers.length / 2 + 1); // Don't scale DC or Nyquist by 2
- if (typeof band === 'string' || band instanceof String) {
- band = bands[band];
- }
+ powers[0] /= 2;
+ powers[powers.length - 1] /= 2; // Compute frequencies
- var startIndex = Math.floor(band[0] / sampleRate * fftSize);
- var endIndex = Math.min(Math.ceil(band[1] / sampleRate * fftSize), psd.length - 1);
- var power = 0;
+ var frequencies = new Array(powers.length);
- for (var i = startIndex; i < endIndex + 1; i++) {
- power += psd[i];
+ for (var _i = 0; _i < frequencies.length; _i++) {
+ frequencies[_i] = _i * (sample_rate / fftSize);
}
- return power / (endIndex - startIndex + 1);
-}
-
-module.exports = psdBandPower;
-
-},{"./nextpow2.js":21}],24:[function(require,module,exports){
-"use strict";
-
-var psd = require('./psd.js');
-
-var psdBandPower = require('./psdBandPower.js');
-
-var nextpow2 = require('./nextpow2.js');
-
-var transpose = require('./transpose.js');
-/**
- * Compute the average power across a given frequency band in a signal.
- * @memberof module:bcijs
- * @param {number[]|number[][]} samples - The signal (array of numbers) or a matrix of signals, where rows are samples and columns are signals.
- * @param {number} sampleRate - The sample rate of the signal.
- * @param {(Array|string)} bands - The frequency band or array of bands, where a single band is provided as an array [frequencyStart, frequencyStop] or a string delta
(1-3 Hz), theta
(4-7 Hz), alpha
(8-12 Hz), beta
(13-30 Hz), or gamma
(31-50 Hz).(a=(o=Math.ceil(u/N))>a?o+1:a+1)&&(i=a,n.length=1),n.reverse();i--;)n.push(0);n.reverse()}for((a=c.length)-(i=f.length)<0&&(i=a,n=f,f=c,c=n),r=0;i;)r=(c[--i]=c[i]+f[i]+r)/_|0,c[i]%=_;for(r&&(c.unshift(r),++e),a=c.length;0==c[--a];)c.pop();return t.d=c,t.e=q(c,e),m?k(t,u,s):t},j.precision=j.sd=function(t){var r,n=this;if(void 0!==t&&t!==!!t&&1!==t&&0!==t)throw Error(y+t);return n.d?(r=D(n.d),t&&n.e+1>r&&(r=n.e+1)):r=NaN,r},j.round=function(){var t=this,r=t.constructor;return k(new r(t),t.e+1,r.rounding)},j.sine=j.sin=function(){var t,r,n=this,e=n.constructor;return n.isFinite()?n.isZero()?new e(n):(t=e.precision,r=e.rounding,e.precision=t+Math.max(n.e,n.sd())+N,e.rounding=1,n=function(t,r){var n,e=r.d.length;if(e<3)return J(t,2,r,r);n=(n=1.4*Math.sqrt(e))>16?16:0|n,r=r.times(Math.pow(5,-n)),r=J(t,2,r,r);for(var i,o=new t(5),a=new t(16),u=new t(20);n--;)i=r.times(r),r=r.times(o.plus(i.times(a.times(i).minus(u))));return r}(e,G(e,n)),e.precision=t,e.rounding=r,k(a>2?n.neg():n,t,r,!0)):new e(NaN)},j.squareRoot=j.sqrt=function(){var t,r,n,e,i,o,a=this,u=a.d,s=a.e,c=a.s,f=a.constructor;if(1!==c||!u||!u[0])return new f(!c||c<0&&(!u||u[0])?NaN:u?a:1/0);for(m=!1,0==(c=Math.sqrt(+a))||c==1/0?(((r=B(u)).length+s)%2==0&&(r+="0"),c=Math.sqrt(r),s=v((s+1)/2)-(s<0||s%2),e=new f(r=c==1/0?"1e"+s:(r=c.toExponential()).slice(0,r.indexOf("e")+1)+s)):e=new f(c.toString()),n=(s=f.precision)+3;;)if(e=(o=e).plus(O(a,o,n+2,1)).times(.5),B(o.d).slice(0,n)===(r=B(e.d)).slice(0,n)){if("9999"!=(r=r.slice(n-3,n+1))&&(i||"4999"!=r)){+r&&(+r.slice(1)||"5"!=r.charAt(0))||(k(e,s+1,1),t=!e.times(e).eq(a));break}if(!i&&(k(o,s+1,0),o.times(o).eq(a))){e=o;break}n+=4,i=1}return m=!0,k(e,s,f.rounding,t)},j.tangent=j.tan=function(){var t,r,n=this,e=n.constructor;return n.isFinite()?n.isZero()?new e(n):(t=e.precision,r=e.rounding,e.precision=t+10,e.rounding=1,(n=n.sin()).s=1,n=O(n,new e(1).minus(n.times(n)).sqrt(),t+10,0),e.precision=t,e.rounding=r,k(2==a||4==a?n.neg():n,t,r,!0)):new e(NaN)},j.times=j.mul=function(t){var r,n,e,i,o,a,u,s,c,f=this,l=f.constructor,p=f.d,h=(t=new l(t)).d;if(t.s*=f.s,!(p&&p[0]&&h&&h[0]))return new l(!t.s||p&&!p[0]&&!h||h&&!h[0]&&!p?NaN:p&&h?0*t.s:t.s/0);for(n=v(f.e/N)+v(t.e/N),(s=p.length)<(c=h.length)&&(o=p,p=h,h=o,a=s,s=c,c=a),o=[],e=a=s+c;e--;)o.push(0);for(e=c;--e>=0;){for(r=0,i=s+e;i>e;)u=o[i]+h[e]*p[i-e-1]+r,o[i--]=u%_|0,r=u/_|0;o[i]=(o[i]+r)%_|0}for(;!o[--a];)o.pop();return r?++n:o.shift(),t.d=o,t.e=q(o,n),m?k(t,l.precision,l.rounding):t},j.toBinary=function(t,r){return W(this,2,t,r)},j.toDecimalPlaces=j.toDP=function(t,r){var n=this,e=n.constructor;return n=new e(n),void 0===t?n:(T(t,0,s),void 0===r?r=e.rounding:T(r,0,8),k(n,t+n.e+1,r))},j.toExponential=function(t,r){var n,e=this,i=e.constructor;return void 0===t?n=I(e,!0):(T(t,0,s),void 0===r?r=i.rounding:T(r,0,8),n=I(e=k(new i(e),t+1,r),!0,t+1)),e.isNeg()&&!e.isZero()?"-"+n:n},j.toFixed=function(t,r){var n,e,i=this,o=i.constructor;return void 0===t?n=I(i):(T(t,0,s),void 0===r?r=o.rounding:T(r,0,8),n=I(e=k(new o(i),t+i.e+1,r),!1,t+e.e+1)),i.isNeg()&&!i.isZero()?"-"+n:n},j.toFraction=function(t){var r,n,e,i,o,a,u,s,c,f,l,p,h=this,g=h.d,d=h.constructor;if(!g)return new d(h);if(c=n=new d(1),e=s=new d(0),a=(o=(r=new d(e)).e=D(g)-h.e-1)%N,r.d[0]=x(10,a<0?N+a:a),null==t)t=o>0?r:c;else{if(!(u=new d(t)).isInt()||u.lt(c))throw Error(y+u);t=u.gt(r)?o>0?r:c:u}for(m=!1,u=new d(B(g)),f=d.precision,d.precision=o=g.length*N*2;l=O(u,r,0,1,1),1!=(i=n.plus(l.times(e))).cmp(t);)n=e,e=i,i=c,c=s.plus(l.times(i)),s=i,i=r,r=u.minus(l.times(i)),u=i;return i=O(t.minus(n),e,0,1,1),s=s.plus(i.times(c)),n=n.plus(i.times(e)),s.s=c.s=h.s,p=O(c,e,o,1).minus(h).abs().cmp(O(s,n,o,1).minus(h).abs())<1?[c,e]:[s,n],d.precision=f,m=!0,p},j.toHexadecimal=j.toHex=function(t,r){return W(this,16,t,r)},j.toNearest=function(t,r){var n=this,e=n.constructor;if(n=new e(n),null==t){if(!n.d)return n;t=new e(1),r=e.rounding}else{if(t=new e(t),void 0!==r&&T(r,0,8),!n.d)return t.s?n:t;if(!t.d)return t.s&&(t.s=n.s),t}return t.d[0]?(m=!1,r<4&&(r=[4,5,7,8][r]),n=O(n,t,0,r,1).times(t),m=!0,k(n)):(t.s=n.s,n=t),n},j.toNumber=function(){return+this},j.toOctal=function(t,r){return W(this,8,t,r)},j.toPower=j.pow=function(t){var r,n,e,i,o,a,u=this,s=u.constructor,c=+(t=new s(t));if(!(u.d&&t.d&&u.d[0]&&t.d[0]))return new s(x(+u,c));if((u=new s(u)).eq(1))return u;if(e=s.precision,o=s.rounding,t.eq(1))return k(u,e,o);if((r=v(t.e/N))>=t.d.length-1&&(n=c<0?-c:c)<=9007199254740991)return i=R(s,u,n,e),t.s<0?new s(1).div(i):k(i,e,o);if((a=u.s)<0){if(r