summaryrefslogtreecommitdiff
path: root/macros/goertzel.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/goertzel.sci')
-rw-r--r--macros/goertzel.sci79
1 files changed, 79 insertions, 0 deletions
diff --git a/macros/goertzel.sci b/macros/goertzel.sci
new file mode 100644
index 0000000..bc0061c
--- /dev/null
+++ b/macros/goertzel.sci
@@ -0,0 +1,79 @@
+function Y = goertzel(X,INDVEC,DIM)
+//Computes DFT using the second order Goertzel Algorithm
+//Calling Sequence
+//Y = goertzel(X,INDVEC,DIM)
+//Parameters
+//X
+//A vector matrix or n-dimensional array
+//INDVEC
+//The indices at which the DFT is to be computed
+//DIM
+//The dimension along which the algorithm is to be implemented
+//Description
+//goertzel(X,INDVEC)
+//Computes the DFT of X at indices INDVEC using the second order algorithm along
+//the first non-singleton dimension. Elements of INDVEC must be positive integers
+//less than the length of the first non-singleton dimension. If INDVEC is empty
+//the DFT is computed at all indices along the first non-singleton dimension
+//goertzel(X,INDVEC,DIM)
+//Implements the algorithm along dimension DIM
+//In general goertzel is slower than fft when computing the DFT for all indices
+//along a particular dimension. However it is computationally more efficient when
+//the DFT at only a subset of indices is desired
+//Example
+//x=rand(1,5)
+//x =
+//
+// 0.6283918 0.8497452 0.6857310 0.8782165 0.0683740
+//y=goertzel(x,2);
+//y =
+//
+// - 0.3531539 - 0.6299881i
+//Author
+//Ankur Mallick
+//References
+//Goertzel, G. (January 1958), "An Algorithm for the Evaluation of Finite Trigonometric Series", American Mathematical Monthly 65 (1): 34–35, doi:10.2307/2310304
+ funcprot(0);
+ if(argn(2)<3|isempty(DIM))
+ DIM=find(size(X)>1,1); //First non-singleton dimension
+ end
+ if(DIM>ndims(X))
+ error('Invalid Dimensions');
+ end
+ perm=[DIM, 1:DIM-1, DIM+1:ndims(X)];
+ X=permute(X,perm); //Makes DIM the leading dimension
+ S=size(X);
+ if(argn(2)<2|isempty(INDVEC))
+ INDVEC=1:S(1);
+ end
+ if(max(INDVEC)>S(1)|min(INDVEC)<1)
+ error('Index out of bounds');
+ elseif(or(INDVEC~=round(INDVEC)))
+ error('Indices must be integers');
+ end
+ X1=matrix(X,1,prod(S));
+ T=[type(X1), type(INDVEC), type(DIM)]; //all inputs should be of type double
+ if(~and(T==1))
+ error('Invalid data type');
+ end
+ //Implementing Goertzel algorithm
+ len=[length(INDVEC), S(2:length(S))];
+ Y=matrix(zeros(1,prod(len)),len);
+ v=ones(length(INDVEC),1);
+ w=(2*%pi*(INDVEC-1)/S(1))';
+ re=2*cos(w);
+ im=sin(w);
+ for i=1:prod(S(2:length(S)))
+ x=X(:,i)
+ sp1=0;
+ sp2=0;
+ for j=1:S(1)
+ s=x(j)*v+re.*sp1-sp2;
+ sp2=sp1;
+ sp1=s;
+ end
+ Y(:,i)=((re/2)+im*%i).*sp1-sp2;
+ end
+ iperm(perm)=1:length(perm);
+ Y=permute(Y,iperm); //Converting Y to the original shape of X
+endfunction