• Tidak ada hasil yang ditemukan

Function ‘fft plus.m’ for Discrete Fourier Transforms

50 % (2) The MathWorks (MATLAB company) Documentation Center page, "Fast

51 % Fourier Transform" explains the practical basics, as well as some of the

52 % theory of FFTs, link:

53 % http://www.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html

54

55 % (3) The MathWorks Documentation Center page on the ’fft’ function

56 % supplements the above, link:

57 % http://www.mathworks.com/help/matlab/ref/fft.html

58

59 % (4) The MathWorks Documentation Center page on "Power Spectral Density

60 % Estimates Using FFT" informed this function’s power output option. Link:

61 % http://www.mathworks.com/help/signal/ug/psd-estimate-using-fft.html

62

63 % (5) The MathWorks Documentation Center page on "Amplitude Estimation and

64 % Zero Padding" informs this function’s option of using zero-padding and is

65 % important to spectroscopy, link:

66 % http://www.mathworks.com/help/signal/ug/amplitude-estimation-and-zero-padding.html

67

68 % (6) Short presentation online, "FFT Normalisation for Beginners",

69 % concering total power in wave, link:

70 % http://www.hep.ucl.ac.uk/~rjn/saltStuff/fftNormalisation.pdf

71

72 %% PERFORM THE FFT, INITIAL PROCESSING OF RESULTS

73

74 % The size of the orignal time-series data is the window length; this can

75 % be extended with zero padding.

76

77 length_signal = length(data_signal);

78 if (num_zeroPad > 0) % user wants zero-padding

79 num_fftPts = 2^(nextpow2(length_signal)+(num_zeroPad-1));

80 else % user does not want zero-padding

81 num_fftPts = length_signal;

82 end

83

84 % Perform the fft, with number of points as calculated above.

85 F = fft(data_signal,num_fftPts);

86

87 % Calculate frequency step size

88 deltaFreq = rate_sample/num_fftPts;

89

90 % Calculate the Nyquist frequency

91 Nyq = rate_sample/2;

92

93 % Create the (inital) frequency axis (correct spacing, but runs to sample

94 % frequency)

95 f = (0:(num_fftPts-1))*deltaFreq;

96 % Adjust frequency axis to have negative frequencies (i.e. only <= Nyquist

97 % frequency content).

98 f(f>Nyq) = f(f>Nyq)-(Nyq*2);

99 % Alternatively (to above), could have done below, as the vector elements

100 % in the range of (floor(end/2)+2:end) are/correspond to negative

101 % frequencies (for both even/odd # of fft points)(and mirror the positive

102 % frequency terms).

103 %f(floor(end/2)+2:end) = f(floor(end/2)+2:end) - (Nyq*2);

104

105 %% CONVERT FFT RESULTS TO SELECTED OUTPUT TYPE

106

107 switch case_output

108

109 case 0 % COMPLEX FFT RESULTS - ALL FREQUENCIES (INCLUDING NEGATIVE)

110 % Values for this case already calculated above, just pass along.

111

112 output_fft = F;

113 output_freqaxis = f;

114

115 case 1 % COMPLEX FFT RESULTS - DC TO POSITIVE FREQUENCIES

116 % Similar to case 0 above, but only pass DC and positive

117 % frequencies. Useful for real signals, which is the usual

118 % application.

119

120 % note to self, set up like case 0 but also mult DC and Nyquist (if

121 % present by 2)

122 % Set output frequency axis as positive frequencies.

123 output_freqaxis = f(f>=0);

124 % Alternatively (to above), could have used fact that vector

125 % elements in range of (1:ceil(end/2)) are the DC and positive

126 % frequencies (for both even/odd # of fft points). Would also need

127 % to account for Nyquist component in case of even # fft points.

128 %output_freqaxis = f(1:(ceil(end/2)+(1-mod(num_fftPts,2))))

129

130 % Pass along complex Fourier terms as they are (no amp(), etc.)

131 output_fft = F(f>=0);

132 % Normalize to window length

133 output_fft = output_fft/length_signal;

134

135 % Double non-unique frequency components (i.e. those other than

136 % DC and, if present, Nyquist) as taking single sideband spectrum

137 % of a real signal.

138 output_fft(2:ceil(num_fftPts/2)) = output_fft(2:ceil(num_fftPts/2))*2;

139

140 case 2 % AMPLITUDE

141 % Need to select only DC and positive frequencies for axis. And to

142 % take real amplitude of complex Fourier coefficients.

143

144 % Set output frequency axis as positive frequencies - same as in

145 % complex case (#1) above.

146 output_freqaxis = f(f>=0);

147

148 % Take real amplitude of complex Fourier terms (in elements

149 % corresponding to positive frequencies as above for frequency

150 % axis)(and could instead select such elements with ’ceil’, ’mod’,

151 % etc. as alternatively suggested above).

152 output_fft = abs(F(f>=0));

153 % Normalize to window length

154 output_fft = output_fft/length_signal;

155 % Multiply non-unique components by 2 as in above case.

156 output_fft(2:ceil(num_fftPts/2)) = output_fft(2:ceil(num_fftPts/2))*2;

157

158 case 3 % POWER (simple square of amplitude)

159 % Square the amplitude values and divide by the number of FFT points.

160

161 % Set output frequency axis as positive frequencies - same as in

162 % complex case (#1) above.

163 output_freqaxis = f(f>=0);

164

165 % Take the amplitudes as in amplitude case above, square, divide by

166 % number of FFT points.

167 output_fft = abs(F(f>=0)).^2;

168

169 % Multiply non-unique components by 2 as in above case.

170 output_fft(2:ceil(num_fftPts/2)) = output_fft(2:ceil(num_fftPts/2))*2;

171

172 case 4 % POWER (sum squared amplitude)

173 % Square the amplitude values and divide by the number of FFT points.

174

175 % Set output frequency axis as positive frequencies - same as in

176 % complex case (#1) above.

177 output_freqaxis = f(f>=0);

178

179 % Take the amplitudes as in amplitude case above, square, divide by

180 % number of FFT points.

181 output_fft = (1/num_fftPts).*abs(F(f>=0)).^2;

182

183 % Multiply non-unique components by 2 as in above case.

184 output_fft(2:ceil(num_fftPts/2)) = output_fft(2:ceil(num_fftPts/2))*2;

185

186 case 5 % POWER SPECTRAL DENSITY (linear power per Hz)

187 % Very similar to power case above, but scale differently for ’per

188 % Hz’ spectral density.

189

190 % Set output frequency axis as above.

191 output_freqaxis = f(f>=0);

192

193 % Take the amplitudes as in power case above, but change

194 % pre-factor.

195 output_fft = (1/(rate_sample*num_fftPts)).*abs(F(f>=0)).^2;

196

197 % Multiply non-unique components by 2 as in above case.

198 output_fft(2:ceil(num_fftPts/2)) = output_fft(2:ceil(num_fftPts/2))*2;

199

200 otherwise % user selected undefined value for ’case_output’

201 % Let use know of the problem and pass along zeros.

202

203 disp(’Error in fft_plus function: improper case_output value’)

204 output_freqaxis = 0;

205 output_fft = 0;

206

207 end

208

209 end