summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoravinashlalotra2025-03-14 17:31:50 +0530
committeravinashlalotra2025-03-14 17:31:50 +0530
commitda8485388b50f3358335c93aec650a84a34e6c62 (patch)
treea059dc114d0b4c237efb672e27943756c970f9d0
parentfabcfd2e08a0bc6500097a8db8d6c8fbe55dba07 (diff)
downloadFOSSEE-Signal-Processing-Toolbox-da8485388b50f3358335c93aec650a84a34e6c62.tar.gz
FOSSEE-Signal-Processing-Toolbox-da8485388b50f3358335c93aec650a84a34e6c62.tar.bz2
FOSSEE-Signal-Processing-Toolbox-da8485388b50f3358335c93aec650a84a34e6c62.zip
Winter Internship 2024 work done by Abinash Singh
-rw-r--r--macros/periodgram.sci232
-rw-r--r--macros/sos2cell.sci152
2 files changed, 296 insertions, 88 deletions
diff --git a/macros/periodgram.sci b/macros/periodgram.sci
new file mode 100644
index 0000000..0d406ec
--- /dev/null
+++ b/macros/periodgram.sci
@@ -0,0 +1,232 @@
+// Copyright (C) 2018 - IIT Bombay - FOSSEE
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+// Original Source : https://octave.sourceforge.io/signal/
+// Modifieded by: Abinash Singh Under FOSSEE Internship
+// Last Modified on : Feb 2024
+// Organization: FOSSEE, IIT Bombay
+// Email: toolbox@scilab.in
+
+function [pxx, f] = periodogram (x, varargin)
+ //Calling Sequence:
+ //[PXX, F] = periodogram (X, WIN, NFFT, FS)
+ //[PXX, F] = periodogram (..., "RANGE")
+
+ // The possible inputs are:
+ //
+ // X
+ //
+ // data vector. If X is real-valued a one-sided spectrum is
+ // estimated. If X is complex-valued, or "RANGE" specifies
+ // "twosided", the full spectrum is estimated.
+ //
+ // WIN
+ // window weight data. If window is empty or unspecified a
+ // default rectangular window is used. Otherwise, the window is
+ // applied to the signal ('X .* WIN') before computing the
+ // periodogram. The window data must be a vector of the same
+ // length as X.
+ //
+ // NFFT
+ // number of frequency bins. The default is 256 or the next
+ // higher power of 2 greater than the length of X ('max (256,
+ // 2.^nextpow2 (length (x)))'). If NFFT is greater than the
+ // length of the input then X will be zero-padded to the length
+ // of NFFT.
+ //
+ // FS
+ // sampling rate. The default is 1.
+ //
+ // RANGE
+ // range of spectrum. "onesided" computes spectrum from
+ // [0..nfft/2+1]. "twosided" computes spectrum from [0..nfft-1].
+ //
+ //
+ // Dependencies
+ // hamming fft1
+ [nargout,nargin]=argn();
+ // check input arguments
+ if (nargin < 1 | nargin > 5)
+ error("wrong no. of input arguments")
+ end
+
+ nfft = [];
+ fs = [];
+ ran = "";
+ win = [];
+ j = 2;
+ for k = 1:length (varargin)
+ if (type (varargin(k))==10)
+ ran = varargin(k);
+ else
+ select (j)
+ case 2
+ win = varargin(k);
+ case 3
+ nfft = varargin(k);
+ case 4
+ fs = varargin(k);
+ end
+ j=j+1;
+ end
+ end
+
+ if (~ isvector (x))
+ error ("periodogram: X must be a real or complex vector");
+ end
+ x = x(:); // Use column vectors from now on
+
+ n = size(x,1);
+
+ if (~isempty (win))
+ if (~ isvector (win) | length (win) ~= n)
+ error ("periodogram: WIN must be a vector of the same length as X");
+ end
+ win = win(:);
+ x =x.* win;
+ else
+ win=window("re",length(x));
+ win=win(:);
+ x=x.*win;
+
+ end
+
+ if (isempty (nfft))
+ nfft = max (256, 2.^nextpow2 (n));
+ elseif (~ isscalar (nfft))
+ error ("periodogram: NFFT must be a scalar");
+ end
+
+ use_w_freq = isempty (fs);
+ if (~use_w_freq & ~ isscalar (fs))
+ error ("periodogram: FS must be a scalar");
+ end
+
+ if (~strcmp (ran, "onesided"))
+ ran = 1;
+ elseif (~strcmp (ran, "twosided"))
+ ran = 2;
+ elseif (~strcmp (ran, "centered"))
+ error ('periodogram: centered ran type is not implemented');
+ else
+ ran = 2 - double(isreal (x));
+ end
+
+ // compute periodogram
+
+ if (n > nfft)
+ Pxx = 0;
+ rr = modulo(length(x), nfft);
+ if (rr)
+ x = [x(:); zeros(nfft-rr, 1)];
+ end
+ x = sum (matrix (x, nfft,-1), 2);
+ end
+
+ if (~ isempty (win))
+ n = sum(win.*conj(win));
+ end;
+
+ Pxx = (abs (fft1 (x,nfft))) .^ 2 / n;
+
+ if (use_w_freq)
+ Pxx =Pxx/(2*%pi);
+ else
+ Pxx =Pxx/fs;
+ end
+
+ // generate output arguments
+
+ if (ran == 1) // onesided
+ if (modulo(nfft,2)==0) // nfft is even
+ psd_len = (nfft/2)+1;
+ Pxx = Pxx(1:psd_len) + [0; Pxx(nfft:-1:psd_len+1); 0];
+ else // nfft is odd
+ psd_len = (nfft+1)/2;
+ Pxx = Pxx(1:psd_len) + [0; Pxx(nfft:-1:psd_len+1)];
+ end
+ end
+
+ //if (nargout() ~= 1) FIXME: fix nargout
+ if (ran == 1)
+ f = (0:nfft/2)' / nfft;
+ elseif (ran == 2)
+ f = (0:nfft-1)' / nfft;
+ end
+ if (use_w_freq)
+ f =f* 2*%pi; // generate w=2*pi*f
+ else
+ f =f* fs;
+ end
+ //end
+ if (nargout() ~= 2)
+ if (use_w_freq)
+ plot (f/(2*%pi), 10*log10 (Pxx));
+ xlabel ("normalized frequency [x pi rad]");
+ ylabel ("Power density [dB/rad/sample]");
+ else
+ plot (f, 10*log10 (Pxx));
+ xlabel ("frequency [Hz]");
+ ylabel ("Power density [dB/Hz]");
+ end
+ title ("Periodogram Power Spectral Density Estimate");
+ end
+ pxx = Pxx;
+endfunction
+
+/*
+pi = %pi; // ezecute on scilab only
+
+t = 0:0.01:1;
+x = sin(2*pi*10*t);
+periodogram(x);
+
+x = complex(0:0.01:1, 0:0.01:1);
+periodogram(x);
+
+x = cos(0:0.01:1);
+win = hamming(101);
+periodogram(x, win);
+
+
+
+x = tan(0:0.01:1);
+nfft = 512;
+periodogram(x, [], nfft);
+
+
+t = 0:0.01:1;
+x = sin(2*pi*10*t);
+Fs = 100;
+periodogram(x, [], [], Fs)
+
+
+
+x = sin(0:0.01:1);
+periodogram(x, [], [], [], 'onesided');
+
+x = sin(0:0.01:1);
+periodogram(x, [], [], [], 'twosided')
+
+
+Fs = 1000;
+t = 0:1/Fs:1-1/Fs;
+f0 = 100;
+x = sin(2*pi*f0*t);
+[Pxx, f] = periodogram(x, [], [], Fs);
+[_, idx] = max(Pxx);
+detected_freq = f(idx);
+
+
+// Test error : invalid window length
+x = randn(100,1);
+win = hamming(50);
+periodogram(x, win)
+
+// Test invalid nfft (negative)
+periodogram(x, [], -256)
+
+*/
diff --git a/macros/sos2cell.sci b/macros/sos2cell.sci
index be40667..0434c6e 100644
--- a/macros/sos2cell.sci
+++ b/macros/sos2cell.sci
@@ -1,93 +1,69 @@
-function c = sos2cell(s,g)
-//Converts a second order section matrix to a cell array
-//Calling Sequences
-//c=sos2cell(s)
-//c=sos2cell(s,g)
-//Parameters
-//s
-//An L-by-6 matrix where L is the number of sections
-//g
-//The scalar gain
-//Description
-//c=sos2cell(s) converts an L-by-6 second-order-section matrix s given by:
-// s = [B1 A1
-// B2 A2
-// ...
-// BL AL]
-//to a cell array c = { {B1},{A1}, {B2},{A2}, ... {BL},{AL}} where each
-//numerator vector Bi and denominator vector Ai contains the coefficients of a
-//linear or quadratic polynomial. If the polynomial is linear, the coefficients
-//zero-padded on the right
-//c=sos2cell(s,g) adds a leading gain term to the start of the cell array as:
-//c={ {[g,1]},{B1},{A1}, {B2},{A2}, ... {BL},{AL}}
-//Example
-//s=rand(2,6)
-// s =
-//
-//
-// column 1 to 5
-//
-// 0.0437334 0.2639556 0.2806498 0.7783129 0.1121355
-// 0.4818509 0.4148104 0.1280058 0.2119030 0.6856896
-//
-// column 6
-//
-// 0.1531217
-// 0.6970851
-//
-//sos2cell(s,2)
-// ans =
-//
-//
-//
-// column 1 to 3
-//
-//![2,1] [0.0437334,0.2639556,0.2806498] [0.7783129,0.1121355,0.1531217] !
-//
-// column 4 to 5
-//
-//![0.4818509,0.4148104,0.1280058] [0.2119030,0.6856896,0.6970851] !
-//Author
-//Ankur Mallick
- if(argn(2)<2)
- g=[];
+// Copyright (C) 2018 - IIT Bombay - FOSSEE
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+// Author: Abinash Singh Under FOSSEE Internship
+// Organization: FOSSEE, IIT Bombay
+// Email: toolbox@scilab.in
+/*
+Calling Sequence :
+ cll = sos2cell(s)
+ cll = sos2cell(s, g)
+Description
+ sos2cell converts a second-order section matrix to a cell array representation.
+ The function can handle both unity-gain and non-unity gain filter systems. For non-unity gain systems, the gain factor is stored in the first cell of the output array.
+Input Arguments
+ s - Second-order section matrix (L-by-6 matrix)
+ Each row represents one second-order section
+ Must have exactly 6 columns in format: [b0 b1 b2 a0 a1 a2]
+ Number of rows (L) represents the number of sections
+ g - Gain factor (optional)
+ Scalar value representing the system gain
+ Default value is 1 if not specified
+Output Arguments
+ cll - Cell array containing second-order sections
+ For unity-gain systems (no gain specified):
+ Cell array with L elements
+ Each element contains coefficients: {[b0 b1 b2] [a0 a1 a2]}
+ For non-unity gain systems:
+ Cell array with L+1 elements
+ First element contains gain: {g 1}
+ Remaining elements contain section coefficients
+*/
+function cll = sos2cell(s, g)
+ if (argn(2) > 2) then
+ error("sos2cell: Wrong number of input arguments");
+ end
+ gain_inc = 1 ;
+ if nargin < 2 then
+ g = 1 ;
+ gain_inc = 0;
+ end
+ [L, n] = size(s);
+ if n ~= 6 then
+ error("sos2cell: Input matrix must have 6 columns");
end
- if g==1
- g=[];
+ if gain_inc then
+ L = L + 1 ;
end
- if(~or(type(s)==[1 5 8])|ndims(s)~=2|size(s,2)~=6)
- error('Invalid Entry');
+ cll = cell(1,L);
+ start_index=1
+ if gain_inc then
+ cll{1} = { g 1};
+ start_index = 2 ;
end
- L=size(s,1);
- if ((L==1)&(~isempty(g))&(s==[1, 0, 0, 1, 0, 0]))
- s=g*s;
- g=[];
- end
- c=cell(1,2*L);
- k=0;
- if(~isempty(g))
- c=cell(1,2*L+1);
- c(1,1).entries=[g, 1];
- k=1;
- end
- for i=1:2:2*L
- j=ceil(i/2);
- sa=s(j,1:3);
- ma=max(find(sa~=0));
- sb=s(j,4:6);
- mb=max(find(sb~=0));
- cs=cell(1,2);
- if(~isempty(ma))
- cs(1,1).entries=sa(1:ma);
- else
- cs(1,1).entries=[];
- end
- if(~isempty(mb))
- cs(1,2).entries=sb(1:mb);
- else
- cs(1,2).entries=[];
- end
- c(k+i)=cs(1,1);
- c(k+i+1)=cs(1,2);
+ for i=start_index:L
+ cll{i}={s(i+1-start_index,1:3) s(i+1-start_index,4:6)}
end
endfunction
+/*
+sos = [3. 6. 7. 1. 1. 2. ; 1. 4. 5. 1. 9. 3. ; 2. 7. 1. 1. 7. 8.];
+cll = sos2cell(sos); // passed
+
+sos = [3. 6. 7. 1. 1. 2. ; 1. 4. 5. 1. 9. 3. ; 2. 7. 1. 1. 7. 8.];
+g = 0.5 ;
+cll = sos2cell(sos,g); // passed
+
+*/ \ No newline at end of file