I have a noise-free dataset which is a vector of numbers, $$\mathbf{d}$$, with length $$N$$.

I want to "add noise" to this data. My understanding is that there are two ways to do this.

1) Add some percentage of Gaussian noise

$$\mathbf{d_n} = \mathbf{d}+\epsilon\mathbf{dr}$$ where $$\mathbf{d_n}$$ is the noisy signal, $$\epsilon$$ is the amount of noise to be added (e.g. 0.05 or 5%) and $$\mathbf{r}$$ is a $$N$$-length vector of numbers drawn from the Gaussian distribution.

2) Add White Gaussian Noise with an SNR

In MATLAB, there is the awgn(d,s) function which takes $$\mathbf{d}$$ and adds white Gaussian noise to the vector with a signal-to-noise ratio of $$s$$ such that

$$\mathbf{d_n} = \mathbf{d}+\sqrt{10^{-s/10}}\mathbf{r}$$

I can also relate the noise percent ($$\epsilon$$) and signal-to-noise ratio ($$s$$) together with the equation.

$$s = 10\;\mathrm{log}_{10}(1+\epsilon)$$

Using this relation, I think "5% Gaussian noise" is equal to 0.487 SNR.

My question is: Which should I use to add noise to a signal? Which is "correct"?

The two methods give different answers. For example, if I want to compute the normalized r.m.s. misfit between the noise-free and noisy signal I take:

$$rms = \sqrt{\frac{1}{N}\sum_{k}^N\left ( \frac{d(k) - d_n(k)}{\Delta d(k)}\right )}$$

When adding "Gaussian noise", I want the error bar associated with each data point to be defined such that the normalized rms misfit is equal to 1. In the first case, in order to recover an rms misfit of 1.0, I need $$\mathbf{\Delta d} = \epsilon \mathbf{d}$$ whereas in the second case, I need $$\mathbf{\Delta d} = \sqrt{10^{-p/10}}$$. So both methods add the "same amount of noise" (e.g. 5%) but the error bars associated with each data point is different depending on the method! It also seems that, upon visual inspection, the second method adds "more" noise (i.e. the signal looks noisier). The second method also has a constant errorbar whereas the other method has a errorbar which depends on the data.

Below is a code sample and a figure output from MATLAB:

period = 20;
t = linspace(-20, 20, 500);
N = length(t);
noise_level = 0.05; %Gaussian noise level = 5 percent
snr = 10*log10(1+noise_level); %SNR = 0.487

d = 10*sin(2 * pi * t / period); %Noise free data
r =randn(1, N); %Random N-length vector of Gaussian numbers

%Add noise using 5% Gaussian Noise Method
dn_1 = d + noise_level.*r.*d; %Noisy signal
errorbar_1 = noise_level*d; %Data error

%Add noise using 0.487 SNR and White Gaussian Noise
dn_2 = d + sqrt((10^(-snr/10)))*r; %Noisy signal
errorbar_2 = sqrt(10^(-snr/10))*ones(size(d)); %Data error is a vector of ones

%Compute RMS for each method
rms_1 = sqrt((1/N)*sum(((d-dn_1)./errorbar_1).^2));
rms_2 = sqrt((1/N)*sum(((d-dn_2)./errorbar_2).^2));

%Plot results
plot(t,d,'.k'); hold on %Plot noise-free data
plot(t,dn_1,'-b','LineWidth',1) %Plot Method 1 noisy data
plot(t,dn_2,'-r') %Plot Method 2 noisy data
legend('Noise-free Data','5% Gaussian Noise','White Noise SNR = 0.487')