# input2 = np.concatenate((np.concatenate((np.zeros(scale / 2), Atom_test.waveform)), np.zeros(scale / 2))) input1 = 0.01 * np.random.randn(2 * scale) + np.concatenate( (np.concatenate((np.zeros(scale / 2 - ts), Atom_test.waveform)), np.zeros(scale / 2 + ts)) ) input3 = np.array(input2) input4 = np.array(input1) score = np.array([0.0]) import time nbIt = 10000 t = time.clock() for j in range(nbIt): timeShift = parallelProjections.project_atom(input1, input2, score, scale) print "C code Took", time.clock() - t t = time.clock() for j in range(nbIt): Xcor = np.correlate(input4, input3, "full") # maxI = abs(Xcor).argmax(); # max = abs(Xcor).max(); print "Numpy took ", time.clock() - t # print "See if numpy correlate is efficient" # print score , abs(Xcor).max(); # print timeShift , abs(Xcor).argmax() - 255; # scoreOld = np.array([0.0]);
def getMaxAtom(self , debug = 0): self.maxFrameIdx = floor(self.maxIdx / (0.5*self.scale)) self.maxBinIdx = self.maxIdx - self.maxFrameIdx * (0.5*self.scale) # hack here : let us project the atom waveform on the neighbouring signal in the FFt domain, # so that we can find the maximum correlation and best adapt the time-shift Atom = atom.Atom(self.scale , 1 , max((self.maxFrameIdx * self.scale/2) - self.scale/4 , 0) , self.maxBinIdx , self.residualSignal.samplingFrequency) Atom.frame = self.maxFrameIdx # re-compute the atom amplitude for IMDCT # if self.maxValue.real < 0: # self.maxValue = -abs(self.maxValue) # else: # self.maxValue = abs(self.maxValue) Atom.mdct_value = self.maxValue # new version : compute also its waveform through inverse MDCT Atom.waveform = self.synthesizeAtom(value=1) Atom.timeShift = 0 Atom.projectionScore = 0.0 input1 = self.enframedDataMatrix[(self.maxFrameIdx-1.5) * self.scale/2 : (self.maxFrameIdx+2.5) * self.scale/2] input2 = concatenate( (concatenate((zeros(self.scale/2) , Atom.waveform) ) , zeros(self.scale/2) ) ) # debug cases: sometimes when lot of energy on the borders , pre-echo artifacts tends # to appears on the border and can lead to seg fault if not monitored # therefore we need to prevent any time shift leading to positions outside of original signals # ie in the first and last frames. # if debug>0: # print self.maxFrameIdx , self.maxIdx , self.frameNumber # if self.maxFrameIdx ==1: # plt.figure() # plt.plot(Atom.waveform) # plt.plot(self.enframedDataMatrix[0 : Atom.timePosition + Atom.length],'r') # plt.show() # # print (self.maxFrameIdx-1.5) * self.scale/2 , (self.maxFrameIdx+2.5) * self.scale/2 # print len(input1) , len(input2) if len(input1) != len(input2): print self.maxFrameIdx , self.maxIdx , self.frameNumber print len(input1) , len(input2) #if debug>0: print "atom in the borders , no timeShift calculated" return Atom # retrieve additional timeShift if self.useC: scoreVec = array([0.0]) Atom.timeShift = parallelProjections.project_atom(input1,input2 , scoreVec , self.scale) if abs(Atom.timeShift) > Atom.length/2: print "out of limits: found time shift of" , Atom.timeShift Atom.timeShift = 0 return Atom self.maxTimeShift = Atom.timeShift Atom.timePosition += Atom.timeShift # retrieve newly projected waveform Atom.projectionScore = scoreVec[0] Atom.waveform *= Atom.projectionScore # Atom.waveform = input2[self.scale/2:-self.scale/2] else: sigFft = fft(self.enframedDataMatrix[(self.maxFrameIdx-1.5) * self.scale/2 : (self.maxFrameIdx+2.5) * self.scale/2] , 2*self.scale) atomFft = fft(concatenate( (concatenate((zeros(self.scale/2) , Atom.waveform) ) , zeros(self.scale/2) ) ) , 2*self.scale) Atom.timeShift , score = Xcorr.GetMaxXCorr(atomFft , sigFft , maxlag =self.scale/2) self.maxTimeShift = Atom.timeShift Atom.projectionScore = score # print "found correlation max of " , float(score)/sqrt(2/float(self.scale)) # CAses That might happen: time shift result in choosing another atom instead if abs(Atom.timeShift) > Atom.length/2: print "out of limits: found time shift of" , Atom.timeShift Atom.timeShift = 0 return Atom Atom.timePosition += Atom.timeShift # now let us re-project the atom on the signal to adjust it's energy: Only if no pathological case # TODO optimization : pre-compute energy (better: find closed form) if score <0: Atom.amplitude = -sqrt(-score) Atom.waveform = (-sqrt(-score/sum(Atom.waveform**2)) )*Atom.waveform else: Atom.amplitude = sqrt(score) Atom.waveform = (sqrt(score/sum(Atom.waveform**2)) )*Atom.waveform # projOrtho = sum(Atom.waveform * self.residualSignal.dataVec[Atom.timePosition : Atom.timePosition + Atom.length]) # if score <0: # Atom.amplitude = -1 # Atom.waveform = -Atom.waveform return Atom