Add analysis on the generation of time domain signal to match a PSD

This commit is contained in:
Thomas Dehaeze 2019-12-02 11:23:50 +01:00
parent 37c44ee0d9
commit aaaf94f7c3
12 changed files with 1062 additions and 57 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
figs/psd_comparison.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
figs/psd_ground_motion.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
figs/psd_original.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
figs/signal_time_domain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2019-08-15 jeu. 12:31 -->
<!-- 2019-12-02 lun. 11:22 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Compute Spectral Densities of signals with Matlab</title>
@ -270,29 +270,77 @@ for the JavaScript code in this tag.
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="org-div-home-and-up">
<a accesskey="h" href="./index.html"> UP </a>
|
<a accesskey="H" href="./index.html"> HOME </a>
</div><div id="content">
<div id="content">
<h1 class="title">Compute Spectral Densities of signals with Matlab</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org7cc41f2">1. Sensitivity of the instrumentation</a></li>
<li><a href="#orgac6792b">2. Convert the time domain from volts to velocity</a></li>
<li><a href="#org01a363c">3. Power Spectral Density and Amplitude Spectral Density</a></li>
<li><a href="#org90edcdd">4. Modification of a signal's Power Spectral Density when going through an LTI system</a></li>
<li><a href="#orgfb2734c">5. From PSD of the velocity to the PSD of the displacement</a></li>
<li><a href="#org9310776">1. Spectral Analysis - Basics</a>
<ul>
<li><a href="#org2041123">1.1. PSD of ADC quantization noise</a></li>
<li><a href="#orgb854582">1.2. Sensitivity of the instrumentation</a></li>
<li><a href="#org78ed1de">1.3. Convert the time domain from volts to velocity</a></li>
<li><a href="#org8775e6e">1.4. Power Spectral Density and Amplitude Spectral Density</a></li>
<li><a href="#orgcba62e6">1.5. Modification of a signal's Power Spectral Density when going through an LTI system</a></li>
<li><a href="#org3adf2bb">1.6. From PSD of the velocity to the PSD of the displacement</a></li>
<li><a href="#org83b26dc">1.7. Cumulative Power/Amplitude Spectrum</a></li>
<li><a href="#org5ace856">1.8. <span class="todo TODO">TODO</span> Add best practices from the Article and simple snippet that works</a></li>
</ul>
</li>
<li><a href="#orga6e1da0">2. Technique 1 : Approximation with a transfer function</a>
<ul>
<li><a href="#orge44fa26">2.1. Signal's PSD</a></li>
<li><a href="#org35e87c7">2.2. Transfer Function that approximate the ASD</a></li>
<li><a href="#org5b0597b">2.3. Generated Time domain signal</a></li>
<li><a href="#org2bb9116">2.4. Comparison of the Power Spectral Densities</a></li>
<li><a href="#org6d66594">2.5. Simulink</a></li>
</ul>
</li>
<li><a href="#orgd4fbbd9">3. Technique 2 : IFFT</a>
<ul>
<li><a href="#org98e4f2a">3.1. Signal's PSD</a></li>
<li><a href="#orgcb607b3">3.2. Algorithm</a></li>
<li><a href="#org4ff718c">3.3. Obtained Time Domain Signal</a></li>
<li><a href="#orgc9527e8">3.4. PSD Comparison</a></li>
</ul>
</li>
<li><a href="#org7fe2f42">4. <span class="todo TODO">TODO</span> Compute the Noise level and Signal level from PSD</a>
<ul>
<li><a href="#org640e940">4.1. Computation</a></li>
</ul>
</li>
</ul>
</div>
</div>
<p>
This document presents the mathematics as well as the matlab scripts to do the spectral analysis of a measured signal.
This document presents the mathematics as well as the matlab scripts to do various spectral analysis on a measured signal.
</p>
<p>
Some matlab documentation about Spectral Analysis can be found <a href="https://fr.mathworks.com/help/signal/ug/spectral-analysis.html">here</a>.
</p>
<p>
First, in section <a href="#orgd149260">1</a>, some basics of spectral analysis are presented.
</p>
<p>
In some cases, we want to generate a time domain signal with defined Power Spectral Density.
Two methods are presented in sections <a href="#org2ea1c7b">2</a> and <a href="#org84b5cd1">3</a>.
</p>
<p>
Finally, some notes are done on how to compute the noise level and signal level from a given Power Spectral Density in section <a href="#org7bce553">4</a>.
</p>
<div id="outline-container-org9310776" class="outline-2">
<h2 id="org9310776"><span class="section-number-2">1</span> Spectral Analysis - Basics</h2>
<div class="outline-text-2" id="text-1">
<p>
<a id="orgd149260"></a>
</p>
<p>
Typically this signal is coming from an inertial sensor, a force sensor or any other sensor.
</p>
@ -300,10 +348,85 @@ Typically this signal is coming from an inertial sensor, a force sensor or any o
<p>
We here take the example of a signal coming from a Geophone measurement the vertical velocity of the floor at the ESRF.
</p>
</div>
<div id="outline-container-org7cc41f2" class="outline-2">
<h2 id="org7cc41f2"><span class="section-number-2">1</span> Sensitivity of the instrumentation</h2>
<div class="outline-text-2" id="text-1">
<div id="outline-container-org2041123" class="outline-3">
<h3 id="org2041123"><span class="section-number-3">1.1</span> PSD of ADC quantization noise</h3>
<div class="outline-text-3" id="text-1-1">
<p>
This is taken from <a href="https://www.allaboutcircuits.com/technical-articles/quantization-nois-amplitude-quantization-error-analog-to-digital-converters/">here</a>.
</p>
<p>
Let's note:
</p>
<ul class="org-ul">
<li>\(q\) is the corresponding value in [V] of the least significant bit (LSB)</li>
<li>\(\Delta V\) is the full range of the ADC in [V]</li>
<li>\(n\) is the number of ADC's bits</li>
<li>\(f_s\) is the sample frequency in [Hz]</li>
</ul>
<p>
Let's suppose that the ADC is ideal.
The only noise comes from the quantization error.
Interestingly, the noise amplitude is uniformly distributed.
</p>
<p>
The quantization noise can take a value between \(\pm q/2\), and the probability density function is constant in this range (i.e., its a uniform distribution).
Since the integral of the probability density function is equal to one, its value will be \(1/q\) for \(-q/2 < e < q/2\) (Fig. <a href="#orgee629ae">1</a>).
</p>
<div id="orgee629ae" class="figure">
<p><img src="figs/probability_density_function_adc.png" alt="probability_density_function_adc.png" />
</p>
<p><span class="figure-number">Figure 1: </span>Probability density function \(p(e)\) of the ADC error \(e\)</p>
</div>
<p>
Now, we can calculate the time average power of the quantization noise as
</p>
\begin{equation}
P_q = \int_{-q/2}^{q/2} e^2 p(e) de = \frac{q^2}{12}
\end{equation}
<p>
The other important parameter of a noise source is the power spectral density (PSD), which indicates how the noise power spreads in different frequency bands.
To find the power spectral density, we need to calculate the Fourier transform of the autocorrelation function of the noise.
</p>
<p>
Assuming that the noise samples are not correlated with one another, we can approximate the autocorrelation function with a delta function in the time domain.
Since the Fourier transform of a delta function is equal to one, the <b>power spectral density will be frequency independent</b>.
Therefore, the quantization noise is white noise with total power equal to \(P_q = \frac{q^2}{12}\).
</p>
<p>
Thus, the two-sided PSD (from \(\frac{-f_s}{2}\) to \(\frac{f_s}{2}\)), we should divide the noise power \(P_q\) by \(f_s\):
</p>
\begin{equation}
\int_{-f_s/2}^{f_s/2} \Gamma(f) d f = f_s \Gamma = \frac{q^2}{12}
\end{equation}
<p>
Finally:
</p>
\begin{equation}
\begin{align}
\Gamma &= \frac{q^2}{12 f_s} \\
&= \frac{\left(\frac{\Delta V}{2^n}\right)^2}{12 f_s} \text{ in } \left[ \frac{V^2}{Hz} \right]
\end{align}
\end{equation}
</div>
</div>
<div id="outline-container-orgb854582" class="outline-3">
<h3 id="orgb854582"><span class="section-number-3">1.2</span> Sensitivity of the instrumentation</h3>
<div class="outline-text-3" id="text-1-2">
<p>
The measured signal \(x\) by the ADC is in Volts.
The corresponding real velocity \(v\) in m/s.
@ -314,17 +437,17 @@ To obtain the real quantity as measured by the sensor, one have to know the sens
</p>
<div id="org0a5ff56" class="figure">
<div id="orgad69fc7" class="figure">
<p><img src="figs/velocity_to_voltage.png" alt="velocity_to_voltage.png" />
</p>
<p><span class="figure-number">Figure 1: </span>Schematic of the instrumentation used for the measurement</p>
<p><span class="figure-number">Figure 2: </span>Schematic of the instrumentation used for the measurement</p>
</div>
</div>
</div>
<div id="outline-container-orgac6792b" class="outline-2">
<h2 id="orgac6792b"><span class="section-number-2">2</span> Convert the time domain from volts to velocity</h2>
<div class="outline-text-2" id="text-2">
<div id="outline-container-org78ed1de" class="outline-3">
<h3 id="org78ed1de"><span class="section-number-3">1.3</span> Convert the time domain from volts to velocity</h3>
<div class="outline-text-3" id="text-1-3">
<p>
Let's say, we know that the sensitivity of the geophone used is
\[ G_g(s) = G_0 \frac{\frac{s}{2\pi f_0}}{1 + \frac{s}{2\pi f_0}} \quad \left[\frac{V}{m/s}\right] \]
@ -348,11 +471,11 @@ And the gain of the amplifier is 1000: \(G_m(s) = 1000\).
</div>
<p>
If \({G_m(s)}^{-1} {G_g(s)}^{-1}\) is proper, we can simulate this dynamical system to go from the voltage to the velocity units (figure <a href="#orgd3dfdc8">2</a>).
If \({G_m(s)}^{-1} {G_g(s)}^{-1}\) is proper, we can simulate this dynamical system to go from the voltage to the velocity units (figure <a href="#orgf9120d4">3</a>).
</p>
<div class="org-src-container">
<pre class="src src-matlab">data = load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'mat/data_028.mat', 'data'</span><span class="org-rainbow-delimiters-depth-1">)</span>; data = data.data;
<pre class="src src-matlab">data = load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'mat/data_028.mat'</span>, <span class="org-string">'data'</span><span class="org-rainbow-delimiters-depth-1">)</span>; data = data.data;
t = data<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">3</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% [s]</span>
x = data<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">-</span>mean<span class="org-rainbow-delimiters-depth-1">(</span>data<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-type">:</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% The offset if removed (coming from the voltage amplifier) [v]</span>
@ -362,17 +485,17 @@ dt = t<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-high
</div>
<div id="orgd3dfdc8" class="figure">
<div id="orgf9120d4" class="figure">
<p><img src="figs/voltage_to_velocity.png" alt="voltage_to_velocity.png" />
</p>
<p><span class="figure-number">Figure 2: </span>Schematic of the instrumentation used for the measurement</p>
<p><span class="figure-number">Figure 3: </span>Schematic of the instrumentation used for the measurement</p>
</div>
<p>
We simulate this system with matlab:
</p>
<div class="org-src-container">
<pre class="src src-matlab">v = lsim<span class="org-rainbow-delimiters-depth-1">(</span>inv<span class="org-rainbow-delimiters-depth-2">(</span>Gg<span class="org-type">*</span>Gm<span class="org-rainbow-delimiters-depth-2">)</span>, v, t<span class="org-rainbow-delimiters-depth-1">)</span>;
<pre class="src src-matlab">v = lsim<span class="org-rainbow-delimiters-depth-1">(</span>inv<span class="org-rainbow-delimiters-depth-2">(</span>Gg<span class="org-type">*</span>Gm<span class="org-rainbow-delimiters-depth-2">)</span>, x, t<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
@ -382,22 +505,22 @@ And we plot the obtained velocity
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, v<span class="org-rainbow-delimiters-depth-1">)</span>;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Time [s]"</span><span class="org-string"><span class="org-rainbow-delimiters-depth-1">)</span></span><span class="org-string">; ylabel</span><span class="org-string"><span class="org-rainbow-delimiters-depth-1">(</span></span><span class="org-string">"Velocity [m/s]"</span><span class="org-rainbow-delimiters-depth-1">)</span>;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Time </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">"</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">"Velocity </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">m/s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">"</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="org4dd86c0" class="figure">
<div id="org8b13b82" class="figure">
<p><img src="figs/velocity_time.png" alt="velocity_time.png" />
</p>
<p><span class="figure-number">Figure 3: </span>Measured Velocity</p>
<p><span class="figure-number">Figure 4: </span>Measured Velocity</p>
</div>
</div>
</div>
<div id="outline-container-org01a363c" class="outline-2">
<h2 id="org01a363c"><span class="section-number-2">3</span> Power Spectral Density and Amplitude Spectral Density</h2>
<div class="outline-text-2" id="text-3">
<div id="outline-container-org8775e6e" class="outline-3">
<h3 id="org8775e6e"><span class="section-number-3">1.4</span> Power Spectral Density and Amplitude Spectral Density</h3>
<div class="outline-text-3" id="text-1-4">
<p>
We now have the velocity in the time domain:
\[ v(t)\ [m/s] \]
@ -437,27 +560,27 @@ ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Power Spectral Densi
The Amplitude Spectral Density (ASD) is the square root of the Power Spectral Density:
</p>
\begin{equation}
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
\end{equation}
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
loglog<span class="org-rainbow-delimiters-depth-1">(</span>f, sqrt<span class="org-rainbow-delimiters-depth-2">(</span>Sv<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Amplitude Spectral Density $<span class="org-type">\</span>left<span class="org-rainbow-delimiters-depth-2">[</span><span class="org-type">\</span>frac<span class="org-rainbow-delimiters-depth-3">{</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">}{</span><span class="org-type">\</span>sqrt<span class="org-rainbow-delimiters-depth-4">{</span>Hz<span class="org-rainbow-delimiters-depth-4">}</span><span class="org-rainbow-delimiters-depth-3">}</span><span class="org-type">\</span>right<span class="org-rainbow-delimiters-depth-2">]</span>$'<span class="org-rainbow-delimiters-depth-1">)</span>
ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Amplitude Spectral Density $\left</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">\frac</span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">{</span></span><span class="org-string">m/s</span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">}{</span></span><span class="org-string">\sqrt</span><span class="org-string"><span class="org-rainbow-delimiters-depth-4">{</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-4">}</span></span><span class="org-string"><span class="org-rainbow-delimiters-depth-3">}</span></span><span class="org-string">\right</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">$'</span><span class="org-rainbow-delimiters-depth-1">)</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org90edcdd" class="outline-2">
<h2 id="org90edcdd"><span class="section-number-2">4</span> Modification of a signal's Power Spectral Density when going through an LTI system</h2>
<div class="outline-text-2" id="text-4">
<div id="outline-container-orgcba62e6" class="outline-3">
<h3 id="orgcba62e6"><span class="section-number-3">1.5</span> Modification of a signal's Power Spectral Density when going through an LTI system</h3>
<div class="outline-text-3" id="text-1-5">
<div id="org9eca4b8" class="figure">
<div id="org5a3eaea" class="figure">
<p><img src="figs/velocity_to_voltage_psd.png" alt="velocity_to_voltage_psd.png" />
</p>
<p><span class="figure-number">Figure 4: </span>Schematic of the instrumentation used for the measurement</p>
<p><span class="figure-number">Figure 5: </span>Schematic of the instrumentation used for the measurement</p>
</div>
<p>
@ -476,14 +599,14 @@ And we also have:
</div>
</div>
<div id="outline-container-orgfb2734c" class="outline-2">
<h2 id="orgfb2734c"><span class="section-number-2">5</span> From PSD of the velocity to the PSD of the displacement</h2>
<div class="outline-text-2" id="text-5">
<div id="outline-container-org3adf2bb" class="outline-3">
<h3 id="org3adf2bb"><span class="section-number-3">1.6</span> From PSD of the velocity to the PSD of the displacement</h3>
<div class="outline-text-3" id="text-1-6">
<div id="orga1a0bc5" class="figure">
<div id="org14e4432" class="figure">
<p><img src="figs/velocity_to_displacement_psd.png" alt="velocity_to_displacement_psd.png" />
</p>
<p><span class="figure-number">Figure 5: </span>Schematic of the instrumentation used for the measurement</p>
<p><span class="figure-number">Figure 6: </span>Schematic of the instrumentation used for the measurement</p>
</div>
<p>
@ -545,7 +668,12 @@ And we have
Note here that we always have
\[ PSD_x \left(f = \frac{1}{2\pi}\right) = PSD_v \left(f = \frac{1}{2\pi}\right) = PSD_a \left(f = \frac{1}{2\pi}\right), \quad \frac{1}{2\pi} \approx 0.16 [Hz] \]
</p>
</div>
</div>
<div id="outline-container-org83b26dc" class="outline-3">
<h3 id="org83b26dc"><span class="section-number-3">1.7</span> Cumulative Power/Amplitude Spectrum</h3>
<div class="outline-text-3" id="text-1-7">
<p>
If we want to compute the Cumulative Power Spectrum:
\[ CPS_v(f) = \int_0^f PSD_v(\nu) d\nu \quad [(m/s)^2] \]
@ -567,15 +695,425 @@ Then, we can obtain the Root Mean Square value of the velocity:
</p>
<div class="org-src-container">
<pre class="src src-matlab">
<pre class="src src-matlab"><span class="org-type">figure</span>;
hold on;
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, cumtrapz<span class="org-rainbow-delimiters-depth-2">(</span>f, Sv<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
hold off;
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Cumulative Power Spectrum <span class="org-rainbow-delimiters-depth-2">[</span>$<span class="org-rainbow-delimiters-depth-3">(</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2$</span><span class="org-rainbow-delimiters-depth-2">]</span><span class="org-type">'</span><span class="org-rainbow-delimiters-depth-1">)</span>
</pre>
</div>
<p>
In order to integrate from high frequency to low frequency:
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
hold on;
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, flip<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-type">-</span>cumtrapz<span class="org-rainbow-delimiters-depth-3">(</span>flip<span class="org-rainbow-delimiters-depth-4">(</span>f<span class="org-rainbow-delimiters-depth-4">)</span>, flip<span class="org-rainbow-delimiters-depth-4">(</span>Sv<span class="org-rainbow-delimiters-depth-4">)</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
hold off;
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>; ylabel<span class="org-rainbow-delimiters-depth-1">(</span>'Cumulative Power Spectrum <span class="org-rainbow-delimiters-depth-2">[</span>$<span class="org-rainbow-delimiters-depth-3">(</span>m<span class="org-type">/</span>s<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2$</span><span class="org-rainbow-delimiters-depth-2">]</span><span class="org-type">'</span><span class="org-rainbow-delimiters-depth-1">)</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org5ace856" class="outline-3">
<h3 id="org5ace856"><span class="section-number-3">1.8</span> <span class="todo TODO">TODO</span> Add best practices from the Article and simple snippet that works</h3>
</div>
</div>
<div id="outline-container-orga6e1da0" class="outline-2">
<h2 id="orga6e1da0"><span class="section-number-2">2</span> Technique 1 : Approximation with a transfer function</h2>
<div class="outline-text-2" id="text-2">
<p>
<a id="org2ea1c7b"></a>
</p>
</div>
<div id="outline-container-orge44fa26" class="outline-3">
<h3 id="orge44fa26"><span class="section-number-3">2.1</span> Signal's PSD</h3>
<div class="outline-text-3" id="text-2-1">
<p>
We load the PSD of the signal we wish to replicate.
</p>
<div class="org-src-container">
<pre class="src src-matlab">load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'./mat/dist_psd.mat'</span>, <span class="org-string">'dist_f'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
We remove the first value with very high PSD.
</p>
<div class="org-src-container">
<pre class="src src-matlab">dist_f.f = dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
dist_f.psd_gm = dist_f.psd_gm<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
The PSD of the signal is shown on figure <a href="#fig:psd_ground_motion">fig:psd_ground_motion</a>.
</p>
<div id="org809f585" class="figure">
<p><img src="figs/psd_ground_motion.png" alt="psd_ground_motion.png" />
</p>
<p><span class="figure-number">Figure 7: </span>PSD of the signal (<a href="./figs/psd_ground_motion.png">png</a>, <a href="./figs/psd_ground_motion.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org35e87c7" class="outline-3">
<h3 id="org35e87c7"><span class="section-number-3">2.2</span> Transfer Function that approximate the ASD</h3>
<div class="outline-text-3" id="text-2-2">
<div class="org-src-container">
<pre class="src src-matlab">G_gm = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">002</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> <span class="org-highlight-numbers-number">3</span>.<span class="org-highlight-numbers-number">169</span><span class="org-type">*</span>s <span class="org-type">+</span> <span class="org-highlight-numbers-number">27</span>.<span class="org-highlight-numbers-number">74</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">32</span>.<span class="org-highlight-numbers-number">73</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">8</span>.<span class="org-highlight-numbers-number">829</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">7</span>.<span class="org-highlight-numbers-number">983</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
</div>
</div>
<div id="outline-container-org5b0597b" class="outline-3">
<h3 id="org5b0597b"><span class="section-number-3">2.3</span> Generated Time domain signal</h3>
<div class="outline-text-3" id="text-2-3">
<div class="org-src-container">
<pre class="src src-matlab">Fs = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
Ts = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>Fs;
t = <span class="org-highlight-numbers-number">0</span><span class="org-type">:</span>Ts<span class="org-type">:</span><span class="org-highlight-numbers-number">500</span>;
u = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>Fs<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span>randn<span class="org-rainbow-delimiters-depth-1">(</span>length<span class="org-rainbow-delimiters-depth-2">(</span>t<span class="org-rainbow-delimiters-depth-2">)</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">u_o = lsim<span class="org-rainbow-delimiters-depth-1">(</span>G_gm, u, t<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, u_o<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
</div>
</div>
<div id="outline-container-org2bb9116" class="outline-3">
<h3 id="org2bb9116"><span class="section-number-3">2.4</span> Comparison of the Power Spectral Densities</h3>
<div class="outline-text-3" id="text-2-4">
<div class="org-src-container">
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>u_o<span class="org-rainbow-delimiters-depth-1">)</span>;
na = <span class="org-highlight-numbers-number">16</span>;
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>u_o, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, Fs<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
Finally, we compare the PSD of the original signal and the obtained signal on figure <a href="#fig:psd_comparison">fig:psd_comparison</a>.
</p>
</div>
</div>
<div id="outline-container-org6d66594" class="outline-3">
<h3 id="org6d66594"><span class="section-number-3">2.5</span> Simulink</h3>
<div class="outline-text-3" id="text-2-5">
<div id="org3a810b6" class="figure">
<p><img src="figs/simulink_psd_generate.png" alt="simulink_psd_generate.png" />
</p>
<p><span class="figure-number">Figure 8: </span>Simulink Schematic</p>
</div>
<p>
The parameters for the <code>Band-Limited White Noise</code> are:
</p>
<ul class="org-ul">
<li>Noise Power: 1</li>
</ul>
<div class="org-src-container">
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>out.u_gm.Data<span class="org-rainbow-delimiters-depth-1">)</span>;
na = <span class="org-highlight-numbers-number">8</span>;
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>out.u_gm.Data, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, <span class="org-highlight-numbers-number">1e3</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-orgd4fbbd9" class="outline-2">
<h2 id="orgd4fbbd9"><span class="section-number-2">3</span> Technique 2 : IFFT</h2>
<div class="outline-text-2" id="text-3">
<p>
<a id="org84b5cd1"></a>
</p>
<p>
The technique comes from <a class='org-ref-reference' href="#preumont94_random_vibrat_spect_analy">preumont94_random_vibrat_spect_analy</a> (section 12.11).
</p>
</div>
<div id="outline-container-org98e4f2a" class="outline-3">
<h3 id="org98e4f2a"><span class="section-number-3">3.1</span> Signal's PSD</h3>
<div class="outline-text-3" id="text-3-1">
<p>
We load the PSD of the signal we wish to replicate.
</p>
<div class="org-src-container">
<pre class="src src-matlab">load<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'./mat/dist_psd.mat'</span>, <span class="org-string">'dist_f'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
We remove the first value with very high PSD.
</p>
<div class="org-src-container">
<pre class="src src-matlab">dist_f.f = dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
dist_f.psd_gm = dist_f.psd_gm<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">3</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
The PSD of the signal is shown on figure <a href="#fig:psd_original">fig:psd_original</a>.
</p>
<div id="org7969683" class="figure">
<p><img src="figs/psd_original.png" alt="psd_original.png" />
</p>
<p><span class="figure-number">Figure 9: </span>PSD of the original signal (<a href="./figs/psd_original.png">png</a>, <a href="./figs/psd_original.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-orgcb607b3" class="outline-3">
<h3 id="orgcb607b3"><span class="section-number-3">3.2</span> Algorithm</h3>
<div class="outline-text-3" id="text-3-2">
<p>
We define some parameters.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Fs = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">(</span>end<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]</span>
N = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span>length<span class="org-rainbow-delimiters-depth-1">(</span>dist_f.f<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Number of Samples match the one of the wanted PSD</span>
T0 = N<span class="org-type">/</span>Fs; <span class="org-comment">% Signal Duration [s]</span>
df = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>T0; <span class="org-comment">% Frequency resolution of the DFT [Hz]</span>
% Also equal to (dist_f.f(<span class="org-highlight-numbers-number">2</span>)<span class="org-type">-</span>dist_f.f(<span class="org-highlight-numbers-number">1</span>))
</pre>
</div>
<p>
We then specify the wanted PSD.
</p>
<div class="org-src-container">
<pre class="src src-matlab">phi = dist_f.psd_gm;
</pre>
</div>
<p>
Create amplitudes corresponding to wanted PSD.
</p>
<div class="org-src-container">
<pre class="src src-matlab">C = zeros<span class="org-rainbow-delimiters-depth-1">(</span>N<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span>,<span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-keyword">for</span> <span class="org-variable-name"><span class="org-constant">i</span></span> = <span class="org-constant"><span class="org-highlight-numbers-number">1</span></span><span class="org-constant">:N/</span><span class="org-constant"><span class="org-highlight-numbers-number">2</span></span>
C<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-constant">i</span><span class="org-rainbow-delimiters-depth-1">)</span> = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>phi<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-constant">i</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>df<span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-keyword">end</span>
</pre>
</div>
<p>
Add random phase to <code>C</code>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">theta = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>rand<span class="org-rainbow-delimiters-depth-1">(</span>N<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span>,<span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Generate random phase [rad]</span>
Cx = <span class="org-rainbow-delimiters-depth-1">[</span><span class="org-highlight-numbers-number">0</span> ; C<span class="org-type">.*</span>complex<span class="org-rainbow-delimiters-depth-2">(</span>cos<span class="org-rainbow-delimiters-depth-3">(</span>theta<span class="org-rainbow-delimiters-depth-3">)</span>,sin<span class="org-rainbow-delimiters-depth-3">(</span>theta<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">]</span>;
Cx = <span class="org-rainbow-delimiters-depth-1">[</span>Cx; flipud<span class="org-rainbow-delimiters-depth-2">(</span>conj<span class="org-rainbow-delimiters-depth-3">(</span>Cx<span class="org-rainbow-delimiters-depth-4">(</span><span class="org-highlight-numbers-number">2</span><span class="org-type">:</span>end<span class="org-rainbow-delimiters-depth-4">)</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">]</span>;;
</pre>
</div>
</div>
</div>
<div id="outline-container-org4ff718c" class="outline-3">
<h3 id="org4ff718c"><span class="section-number-3">3.3</span> Obtained Time Domain Signal</h3>
<div class="outline-text-3" id="text-3-3">
<p>
The time domain data is generated by an inverse FFT.
We normalize the <code>ifft</code> Matlab command.
</p>
<div class="org-src-container">
<pre class="src src-matlab">u = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>sqrt<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>df<span class="org-type">*</span><span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>Fs<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span>ifft<span class="org-rainbow-delimiters-depth-1">(</span>Cx<span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Normalisation of the IFFT</span>
t = linspace<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">0</span>, T0, N<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>; <span class="org-comment">% Time Vector [s]</span>
</pre>
</div>
<div id="org69c5e9c" class="figure">
<p><img src="figs/signal_time_domain.png" alt="signal_time_domain.png" />
</p>
<p><span class="figure-number">Figure 10: </span>Obtained signal in the time domain (<a href="./figs/signal_time_domain.png">png</a>, <a href="./figs/signal_time_domain.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-orgc9527e8" class="outline-3">
<h3 id="orgc9527e8"><span class="section-number-3">3.4</span> PSD Comparison</h3>
<div class="outline-text-3" id="text-3-4">
<p>
We duplicate the time domain signal to have a longer signal and thus a more precise PSD result.
</p>
<div class="org-src-container">
<pre class="src src-matlab">u_rep = repmat<span class="org-rainbow-delimiters-depth-1">(</span>u, <span class="org-highlight-numbers-number">10</span>, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
We compute the PSD of the obtained signal with the following commands.
</p>
<div class="org-src-container">
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>u_rep<span class="org-rainbow-delimiters-depth-1">)</span>;
na = <span class="org-highlight-numbers-number">16</span>;
win = hanning<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>u_rep, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, Fs<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
Finally, we compare the PSD of the original signal and the obtained signal on figure <a href="#fig:psd_comparison">fig:psd_comparison</a>.
</p>
<div id="orgce3ea03" class="figure">
<p><img src="figs/psd_comparison.png" alt="psd_comparison.png" />
</p>
<p><span class="figure-number">Figure 11: </span>Comparison of the PSD of the original signal and the PSD of the obtained signal (<a href="./figs/psd_comparison.png">png</a>, <a href="./figs/psd_comparison.pdf">pdf</a>)</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org7fe2f42" class="outline-2">
<h2 id="org7fe2f42"><span class="section-number-2">4</span> <span class="todo TODO">TODO</span> Compute the Noise level and Signal level from PSD</h2>
<div class="outline-text-2" id="text-4">
<p>
<a id="org7bce553"></a>
</p>
</div>
<div id="outline-container-org640e940" class="outline-3">
<h3 id="org640e940"><span class="section-number-3">4.1</span> Computation</h3>
<div class="outline-text-3" id="text-4-1">
<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> Add table to compare the methods</li>
<li class="off"><code>[&#xa0;]</code> Add some explanations</li>
</ul>
<div class="org-src-container">
<pre class="src src-matlab">N = <span class="org-highlight-numbers-number">10000</span>;
dt = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">001</span>;
t = dt<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">0</span><span class="org-type">:</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>N<span class="org-type">-</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">'</span>;
</pre>
</div>
<p>
Parameters of the signal
</p>
<div class="org-src-container">
<pre class="src src-matlab">asig = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">8</span>; <span class="org-comment">% Amplitude of the signal [V]</span>
fsig = <span class="org-highlight-numbers-number">100</span>; <span class="org-comment">% Frequency of the signal [Hz]</span>
anoi = <span class="org-highlight-numbers-number">1e</span><span class="org-type">-</span><span class="org-highlight-numbers-number">3</span>; <span class="org-comment">% RMS value of the noise</span>
x = anoi<span class="org-type">*</span>randn<span class="org-rainbow-delimiters-depth-1">(</span>N, <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">+</span> asig<span class="org-type">*</span>sin<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>fsig<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>t<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
plot<span class="org-rainbow-delimiters-depth-1">(</span>t, x<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
Compute the PSD of the signal.
</p>
<div class="org-src-container">
<pre class="src src-matlab">nx = length<span class="org-rainbow-delimiters-depth-1">(</span>x<span class="org-rainbow-delimiters-depth-1">)</span>;
na = <span class="org-highlight-numbers-number">8</span>;
win = blackmanharris<span class="org-rainbow-delimiters-depth-1">(</span>floor<span class="org-rainbow-delimiters-depth-2">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-rainbow-delimiters-depth-1">[</span>pxx, f<span class="org-rainbow-delimiters-depth-1">]</span> = pwelch<span class="org-rainbow-delimiters-depth-1">(</span>x, win, <span class="org-highlight-numbers-number">0</span>, <span class="org-rainbow-delimiters-depth-2">[]</span>, <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span>dt<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
Normalization of the PSD.
</p>
<div class="org-src-container">
<pre class="src src-matlab">CG = sum<span class="org-rainbow-delimiters-depth-1">(</span>win<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-1">)</span>;
NG = sum<span class="org-rainbow-delimiters-depth-1">(</span>win<span class="org-type">.^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>nx<span class="org-type">/</span>na<span class="org-rainbow-delimiters-depth-1">)</span>;
fbin = f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">-</span> f<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
pxx_norm = pxx<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>NG<span class="org-type">*</span>fbin<span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span>CG<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">isig = round<span class="org-rainbow-delimiters-depth-1">(</span>fsig<span class="org-type">/</span>fbin<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span>;
</pre>
</div>
<p>
Estimate the Signal magnitude.
</p>
<div class="org-src-container">
<pre class="src src-matlab">srmt = asig<span class="org-type">/</span>sqrt<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Theoretical value of signal magnitude</span>
srms = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>sum<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span>isig<span class="org-type">-</span><span class="org-highlight-numbers-number">5</span><span class="org-type">:</span>isig<span class="org-type">+</span><span class="org-highlight-numbers-number">5</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span>fbin<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Signal spectrum integrated</span>
srmsp = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>pxx<span class="org-rainbow-delimiters-depth-2">(</span>isig<span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-type">*</span> NG<span class="org-type">*</span>fbin<span class="org-type">/</span>CG<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Maximum read off spectrum</span>
</pre>
</div>
<p>
Estimate the noise floor.
</p>
<div class="org-src-container">
<pre class="src src-matlab">nth = anoi<span class="org-type">/</span>sqrt<span class="org-rainbow-delimiters-depth-1">(</span>max<span class="org-rainbow-delimiters-depth-2">(</span>f<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Theoretical value [V/sqrt(Hz)]</span>
inmax = isig<span class="org-type">-</span><span class="org-highlight-numbers-number">20</span>;
nsum = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>sum<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>inmax<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span>fbin<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">/</span> sqrt<span class="org-rainbow-delimiters-depth-1">(</span>f<span class="org-rainbow-delimiters-depth-2">(</span>inmax<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% Signal spectrum integrated</span>
navg = sqrt<span class="org-rainbow-delimiters-depth-1">(</span>mean<span class="org-rainbow-delimiters-depth-2">(</span>pxx<span class="org-rainbow-delimiters-depth-3">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">:</span>inmax<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-comment">% pwelch output averaged</span>
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-type">figure</span>;
hold on;
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, pxx<span class="org-rainbow-delimiters-depth-1">)</span>
plot<span class="org-rainbow-delimiters-depth-1">(</span>f, pxx_norm<span class="org-rainbow-delimiters-depth-1">)</span>
hold off;
xlabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Frequency </span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">[</span></span><span class="org-string">Hz</span><span class="org-string"><span class="org-rainbow-delimiters-depth-2">]</span></span><span class="org-string">'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
ylabel<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Power Spectral Density'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'xscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
<span class="org-type">set</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-variable-name">gca</span>, <span class="org-string">'yscale'</span>, <span class="org-string">'log'</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
</div>
</div>
</div>
<p>
<h1 class='org-ref-bib-h1'>Bibliography</h1>
<ul class='org-ref-bib'><li><a id="preumont94_random_vibrat_spect_analy">[preumont94_random_vibrat_spect_analy]</a> <a name="preumont94_random_vibrat_spect_analy"></a>Andr\'e Preumont, Random Vibration and Spectral Analysis, Springer Netherlands (1994).</li>
</ul>
</p>
</div>
<div id="postamble" class="status">
<p class="author">Author: Dehaeze Thomas</p>
<p class="date">Created: 2019-08-15 jeu. 12:31</p>
<p class="date">Created: 2019-12-02 lun. 11:22</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>

477
index.org
View File

@ -12,7 +12,7 @@
#+HTML_HEAD: <script type="text/javascript" src="./js/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD: <script type="text/javascript" src="./js/readtheorg.js"></script>
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/MEGA/These/LaTeX/}{config.tex}")
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/thesis/latex/}{config.tex}")
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
#+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150
#+PROPERTY: header-args:latex+ :imoutoptions -quality 100
@ -34,13 +34,27 @@
#+PROPERTY: header-args:matlab+ :output-dir figs
:END:
This document presents the mathematics as well as the matlab scripts to do the spectral analysis of a measured signal.
* Introduction :ignore:
This document presents the mathematics as well as the matlab scripts to do various spectral analysis on a measured signal.
Some matlab documentation about Spectral Analysis can be found [[https://fr.mathworks.com/help/signal/ug/spectral-analysis.html][here]].
First, in section [[sec:spectral_analysis_basics]], some basics of spectral analysis are presented.
In some cases, we want to generate a time domain signal with defined Power Spectral Density.
Two methods are presented in sections [[sec:approximate_tf]] and [[sec:approximate_ifft]].
Finally, some notes are done on how to compute the noise level and signal level from a given Power Spectral Density in section [[sec:compute_psd_levels]].
* Spectral Analysis - Basics
<<sec:spectral_analysis_basics>>
** Introduction :ignore:
Typically this signal is coming from an inertial sensor, a force sensor or any other sensor.
We here take the example of a signal coming from a Geophone measurement the vertical velocity of the floor at the ESRF.
* Matlab Init :noexport:ignore:
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
@ -49,7 +63,68 @@ We here take the example of a signal coming from a Geophone measurement the vert
<<matlab-init>>
#+end_src
* Sensitivity of the instrumentation
** PSD of ADC quantization noise
This is taken from [[https://www.allaboutcircuits.com/technical-articles/quantization-nois-amplitude-quantization-error-analog-to-digital-converters/][here]].
Let's note:
- $q$ is the corresponding value in [V] of the least significant bit (LSB)
- $\Delta V$ is the full range of the ADC in [V]
- $n$ is the number of ADC's bits
- $f_s$ is the sample frequency in [Hz]
Let's suppose that the ADC is ideal.
The only noise comes from the quantization error.
Interestingly, the noise amplitude is uniformly distributed.
The quantization noise can take a value between $\pm q/2$, and the probability density function is constant in this range (i.e., its a uniform distribution).
Since the integral of the probability density function is equal to one, its value will be $1/q$ for $-q/2 < e < q/2$ (Fig. [[fig:probability_density_function_adc]]).
#+begin_src latex :file probability_density_function_adc.pdf :post pdf2svg(file=*this*, ext="png") :exports results
\begin{tikzpicture}
\path[fill=black!20!white] (-1, 0) |- (1, 1) |- (-1, 0);
\draw[->] (-2, 0) -- (2, 0) node[above left]{$e$};
\draw[->] (0, -0.5) -- (0, 2) node[below right]{$p(e)$};
\node[below] at (1, 0){$\frac{q}{2}$};
\node[below] at (-1, 0){$-\frac{q}{2}$};
\node[right] at (1, 1){$\frac{1}{q}$};
\end{tikzpicture}
#+end_src
#+name: fig:probability_density_function_adc
#+caption: Probability density function $p(e)$ of the ADC error $e$
#+RESULTS:
[[file:figs/probability_density_function_adc.png]]
Now, we can calculate the time average power of the quantization noise as
\begin{equation}
P_q = \int_{-q/2}^{q/2} e^2 p(e) de = \frac{q^2}{12}
\end{equation}
The other important parameter of a noise source is the power spectral density (PSD), which indicates how the noise power spreads in different frequency bands.
To find the power spectral density, we need to calculate the Fourier transform of the autocorrelation function of the noise.
Assuming that the noise samples are not correlated with one another, we can approximate the autocorrelation function with a delta function in the time domain.
Since the Fourier transform of a delta function is equal to one, the *power spectral density will be frequency independent*.
Therefore, the quantization noise is white noise with total power equal to $P_q = \frac{q^2}{12}$.
Thus, the two-sided PSD (from $\frac{-f_s}{2}$ to $\frac{f_s}{2}$), we should divide the noise power $P_q$ by $f_s$:
\begin{equation}
\int_{-f_s/2}^{f_s/2} \Gamma(f) d f = f_s \Gamma = \frac{q^2}{12}
\end{equation}
Finally:
\begin{equation}
\begin{align}
\Gamma &= \frac{q^2}{12 f_s} \\
&= \frac{\left(\frac{\Delta V}{2^n}\right)^2}{12 f_s} \text{ in } \left[ \frac{V^2}{Hz} \right]
\end{align}
\end{equation}
** Sensitivity of the instrumentation
The measured signal $x$ by the ADC is in Volts.
The corresponding real velocity $v$ in m/s.
@ -75,7 +150,7 @@ To obtain the real quantity as measured by the sensor, one have to know the sens
#+RESULTS: fig:velocity_to_voltage
[[file:figs/velocity_to_voltage.png]]
* Convert the time domain from volts to velocity
** Convert the time domain from volts to velocity
Let's say, we know that the sensitivity of the geophone used is
\[ G_g(s) = G_0 \frac{\frac{s}{2\pi f_0}}{1 + \frac{s}{2\pi f_0}} \quad \left[\frac{V}{m/s}\right] \]
@ -123,7 +198,7 @@ If ${G_m(s)}^{-1} {G_g(s)}^{-1}$ is proper, we can simulate this dynamical syste
We simulate this system with matlab:
#+begin_src matlab
v = lsim(inv(Gg*Gm), v, t);
v = lsim(inv(Gg*Gm), x, t);
#+end_src
And we plot the obtained velocity
@ -144,7 +219,7 @@ And we plot the obtained velocity
#+RESULTS: fig:velocity_time
[[file:figs/velocity_time.png]]
* Power Spectral Density and Amplitude Spectral Density
** Power Spectral Density and Amplitude Spectral Density
We now have the velocity in the time domain:
\[ v(t)\ [m/s] \]
@ -181,7 +256,7 @@ We first have to defined a window:
The Amplitude Spectral Density (ASD) is the square root of the Power Spectral Density:
\begin{equation}
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
\Gamma_{vv}(f) = \sqrt{S_{vv}(f)} \quad \left[ \frac{m/s}{\sqrt{Hz}} \right]
\end{equation}
#+begin_src matlab
@ -201,7 +276,7 @@ The Amplitude Spectral Density (ASD) is the square root of the Power Spectral De
#+CAPTION: Power Spectral Density of the measured velocity
#+RESULTS: fig:asd_velocity
* Modification of a signal's Power Spectral Density when going through an LTI system
** Modification of a signal's Power Spectral Density when going through an LTI system
#+begin_src latex :file velocity_to_voltage_psd.pdf :post pdf2svg(file=*this*, ext="png") :exports results
\begin{tikzpicture}
@ -227,7 +302,7 @@ And we also have:
\Gamma_{yy}(\omega) = \left|G(j\omega)\right| \Gamma_{xx}(\omega)
\end{equation}
* From PSD of the velocity to the PSD of the displacement
** From PSD of the velocity to the PSD of the displacement
#+begin_src latex :file velocity_to_displacement_psd.pdf :post pdf2svg(file=*this*, ext="png") :exports results
\begin{tikzpicture}
@ -284,6 +359,7 @@ And we have
Note here that we always have
\[ PSD_x \left(f = \frac{1}{2\pi}\right) = PSD_v \left(f = \frac{1}{2\pi}\right) = PSD_a \left(f = \frac{1}{2\pi}\right), \quad \frac{1}{2\pi} \approx 0.16 [Hz] \]
** Cumulative Power/Amplitude Spectrum
If we want to compute the Cumulative Power Spectrum:
\[ CPS_v(f) = \int_0^f PSD_v(\nu) d\nu \quad [(m/s)^2] \]
@ -296,8 +372,387 @@ The Cumulative Amplitude Spectrum is then the square root of the Cumulative Powe
Then, we can obtain the Root Mean Square value of the velocity:
\[ v_{\text{rms}} = CAS_v(0) \quad [m/s \ \text{rms}] \]
#+begin_src matlab
#+begin_src matlab :results none
figure;
hold on;
plot(f, cumtrapz(f, Sv));
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Cumulative Power Spectrum [$(m/s)^2$]')
#+end_src
In order to integrate from high frequency to low frequency:
#+begin_src matlab :results none
figure;
hold on;
plot(f, flip(-cumtrapz(flip(f), flip(Sv))));
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Cumulative Power Spectrum [$(m/s)^2$]')
#+end_src
** TODO Add best practices from the Article and simple snippet that works
* Technique 1 : Approximation with a transfer function
<<sec:approximate_tf>>
** Introduction :ignore:
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
** Signal's PSD
We load the PSD of the signal we wish to replicate.
#+begin_src matlab
load('./mat/dist_psd.mat', 'dist_f');
#+end_src
We remove the first value with very high PSD.
#+begin_src matlab
dist_f.f = dist_f.f(3:end);
dist_f.psd_gm = dist_f.psd_gm(3:end);
#+end_src
The PSD of the signal is shown on figure ref:fig:psd_ground_motion.
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm)
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/psd_ground_motion.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:psd_ground_motion
#+CAPTION: PSD of the signal ([[./figs/psd_ground_motion.png][png]], [[./figs/psd_ground_motion.pdf][pdf]])
[[file:figs/psd_ground_motion.png]]
** Transfer Function that approximate the ASD
#+begin_src matlab
G_gm = 0.002*(s^2 + 3.169*s + 27.74)/(s*(s+32.73)*(s+8.829)*(s+7.983)^2);
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, sqrt(dist_f.psd_gm))
plot(dist_f.f, abs(squeeze(freqresp(G_gm, dist_f.f, 'Hz'))))
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
#+end_src
** Generated Time domain signal
#+begin_src matlab
Fs = 2*dist_f.f(end);
Ts = 1/Fs;
t = 0:Ts:500;
u = sqrt(Fs/2)*randn(length(t), 1);
#+end_src
#+begin_src matlab
u_o = lsim(G_gm, u, t);
#+end_src
#+begin_src matlab
figure;
plot(t, u_o);
#+end_src
** Comparison of the Power Spectral Densities
#+begin_src matlab
nx = length(u_o);
na = 16;
win = hanning(floor(nx/na));
[pxx, f] = pwelch(u_o, win, 0, [], Fs);
#+end_src
Finally, we compare the PSD of the original signal and the obtained signal on figure ref:fig:psd_comparison.
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
plot(f, pxx, 'DisplayName', 'Computed')
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
#+end_src
** Simulink
#+name: fig:simulink_psd_generate
#+caption: Simulink Schematic
[[file:figs/simulink_psd_generate.png]]
The parameters for the =Band-Limited White Noise= are:
- Noise Power: 1
#+begin_src matlab
nx = length(out.u_gm.Data);
na = 8;
win = hanning(floor(nx/na));
[pxx, f] = pwelch(out.u_gm.Data, win, 0, [], 1e3);
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
plot(f, pxx, 'DisplayName', 'Computed')
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
#+end_src
* Technique 2 : IFFT
<<sec:approximate_ifft>>
** Introduction :ignore:
The technique comes from cite:preumont94_random_vibrat_spect_analy (section 12.11).
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
** Signal's PSD
We load the PSD of the signal we wish to replicate.
#+begin_src matlab
load('./mat/dist_psd.mat', 'dist_f');
#+end_src
We remove the first value with very high PSD.
#+begin_src matlab
dist_f.f = dist_f.f(3:end);
dist_f.psd_gm = dist_f.psd_gm(3:end);
#+end_src
The PSD of the signal is shown on figure ref:fig:psd_original.
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm)
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/psd_original.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:psd_original
#+CAPTION: PSD of the original signal ([[./figs/psd_original.png][png]], [[./figs/psd_original.pdf][pdf]])
[[file:figs/psd_original.png]]
** Algorithm
We define some parameters.
#+begin_src matlab
Fs = 2*dist_f.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
N = 2*length(dist_f.f); % Number of Samples match the one of the wanted PSD
T0 = N/Fs; % Signal Duration [s]
df = 1/T0; % Frequency resolution of the DFT [Hz]
% Also equal to (dist_f.f(2)-dist_f.f(1))
#+end_src
We then specify the wanted PSD.
#+begin_src matlab
phi = dist_f.psd_gm;
#+end_src
Create amplitudes corresponding to wanted PSD.
#+begin_src matlab
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
#+end_src
Add random phase to =C=.
#+begin_src matlab
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
#+end_src
** Obtained Time Domain Signal
The time domain data is generated by an inverse FFT.
We normalize the =ifft= Matlab command.
#+begin_src matlab
u = 1/(sqrt(2)*df*1/Fs)*ifft(Cx); % Normalisation of the IFFT
t = linspace(0, T0, N+1); % Time Vector [s]
#+end_src
#+begin_src matlab :exports none
figure;
plot(t, u)
xlabel('Time [s]');
ylabel('Amplitude');
xlim([t(1), t(end)]);
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/signal_time_domain.pdf" :var figsize="normal-wide" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:signal_time_domain
#+CAPTION: Obtained signal in the time domain ([[./figs/signal_time_domain.png][png]], [[./figs/signal_time_domain.pdf][pdf]])
[[file:figs/signal_time_domain.png]]
** PSD Comparison
We duplicate the time domain signal to have a longer signal and thus a more precise PSD result.
#+begin_src matlab
u_rep = repmat(u, 10, 1);
#+end_src
We compute the PSD of the obtained signal with the following commands.
#+begin_src matlab
nx = length(u_rep);
na = 16;
win = hanning(floor(nx/na));
[pxx, f] = pwelch(u_rep, win, 0, [], Fs);
#+end_src
Finally, we compare the PSD of the original signal and the obtained signal on figure ref:fig:psd_comparison.
#+begin_src matlab :exports none
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
plot(f, pxx, 'DisplayName', 'Computed')
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/psd_comparison.pdf" :var figsize="wide-normal" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:psd_comparison
#+CAPTION: Comparison of the PSD of the original signal and the PSD of the obtained signal ([[./figs/psd_comparison.png][png]], [[./figs/psd_comparison.pdf][pdf]])
[[file:figs/psd_comparison.png]]
* TODO Compute the Noise level and Signal level from PSD
<<sec:compute_psd_levels>>
** Introduction :ignore:
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
** Computation
- [ ] Add table to compare the methods
- [ ] Add some explanations
#+begin_src matlab
N = 10000;
dt = 0.001;
t = dt*(0:1:N-1)';
#+end_src
Parameters of the signal
#+begin_src matlab
asig = 0.8; % Amplitude of the signal [V]
fsig = 100; % Frequency of the signal [Hz]
anoi = 1e-3; % RMS value of the noise
x = anoi*randn(N, 1) + asig*sin((2*pi*fsig)*t);
#+end_src
#+begin_src matlab
figure;
plot(t, x);
#+end_src
Compute the PSD of the signal.
#+begin_src matlab
nx = length(x);
na = 8;
win = blackmanharris(floor(nx/na));
[pxx, f] = pwelch(x, win, 0, [], 1/dt);
#+end_src
Normalization of the PSD.
#+begin_src matlab
CG = sum(win)/(nx/na);
NG = sum(win.^2)/(nx/na);
fbin = f(2) - f(1);
pxx_norm = pxx*(NG*fbin/(CG)^2);
#+end_src
#+begin_src matlab
isig = round(fsig/fbin)+1;
#+end_src
Estimate the Signal magnitude.
#+begin_src matlab
srmt = asig/sqrt(2) % Theoretical value of signal magnitude
srms = sqrt(sum(pxx(isig-5:isig+5)*fbin)) % Signal spectrum integrated
srmsp = sqrt(pxx(isig) * NG*fbin/CG^2) % Maximum read off spectrum
#+end_src
Estimate the noise floor.
#+begin_src matlab
nth = anoi/sqrt(max(f)) % Theoretical value [V/sqrt(Hz)]
inmax = isig-20;
nsum = sqrt(sum(pxx(1:inmax)*fbin)) / sqrt(f(inmax)) % Signal spectrum integrated
navg = sqrt(mean(pxx(1:inmax))) % pwelch output averaged
#+end_src
#+begin_src matlab
figure;
hold on;
plot(f, pxx)
plot(f, pxx_norm)
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log');
set(gca, 'yscale', 'log');
#+end_src
* Bibliography :ignore:

BIN
mat/dist_psd.mat Normal file

Binary file not shown.

Binary file not shown.

14
ref.bib
View File

@ -1,8 +1,20 @@
@article{schmid12_how_to_use_fft_matlab,
author = {Schmid, Hanspeter},
title = {How To Use the Fft and Matlab's Pwelch Function for Signal and
title = {How To Use the FFT and Matlab's Pwelch Function for Signal and
Noise Simulations and Measurements},
journal = {Institute of Microelectronics},
year = 2012,
keywords = {},
}
@book{preumont94_random_vibrat_spect_analy,
author = {Andr{\'e} Preumont},
title = {Random Vibration and Spectral Analysis},
year = 1994,
publisher = {Springer Netherlands},
url = {https://doi.org/10.1007/978-94-017-2840-9},
DATE_ADDED = {Mon Dec 2 08:52:51 2019},
doi = {10.1007/978-94-017-2840-9},
pages = {nil},
series = {Solid Mechanics and Its Applications},
}