Hopefully this isn't considered too off-topic. I'm working in industry these days and came up with a solution to a signal processing problem we'd been facing. I'd like to get a sense as to whether said solution has been published before or if there are alternatives I should look at, but I'm having trouble searching for this particular signal scenario. I'll describe the signal structure below, and would appreciate any input on how I should be searching the literature.
So I have two signals: one that is pure noise (
noise_only), and one that is very similar noise plus a target signal of interest (
noise_plus_target). In each signal, the noise is actually made up of multiple somewhat-frequency-distinct signals, and the same set of said noise signals contribute to each observed signals additively but with different weights between the two. In theory, we should be able to use information from the
noise_only signal to help remove the noise from the
noise_plus_target signal, and I've come up with a method to achieve this, but I want to know what other solutions might have been already published for this kind of scenario.
In R, code for generating fake signals that match the characteristics of my real signals would be:
library(tidyverse) # define a function to generate simple sinusoid given time and hz sine = function(time,hz) sin(time*(2*pi)*hz) #define a function to scale values to 0:1 scale01 = function(x) (x - min(x)) / diff(range(x)) #specify sample rate sample_rate = 10 #in Hz max_time = 30 #construct a tibble latent_signals = tibble( #specify sampling times (in seconds) time = seq(0,max_time,1/sample_rate) #30s of data #construct some latent noise signals, each at a decently separated Hz , noise1 = sine(time,1/11) , noise2 = sine(time,1/3) , noise3 = sine(time,1) #specify a target signal that will be hidden in the noise # This could take any shape; here I've chosen a bump midway # through the timeseries , target = scale01(dnorm(time,mean=max_time/2,sd=3)) ) #show the latent signals latent_signals %>% tidyr::pivot_longer( cols = -time ) %>% ggplot()+ facet_grid( name ~ . )+ geom_line( mapping = aes( x = time , y = value ) ) #combine the latent signals into two observed signals, with different weights # for each and the latent target only in one latent_signals %>% dplyr::mutate( noise_only = noise1*runif(1,.5,1.5) + noise2*runif(1,.5,1.5) + noise3*runif(1,.5,1.5) , noise_plus_target = noise1*runif(1,.5,1.5) + noise2*runif(1,.5,1.5) + noise3*runif(1,.5,1.5) + target ) %>% dplyr::select( time , contains('_') ) -> observed_signals #show the observed signals observed_signals %>% tidyr::pivot_longer( cols = -time ) %>% ggplot()+ facet_grid( name ~ . )+ geom_line( mapping = aes( x = time , y = value ) ) ```