def blocks(self): pySig = signals.InitFromFile(audioFilePath+'glocs.wav',forceMono=True); # pySig.crop(0, 5*pySig.samplingFrequency); pySig.crop(0, 16384); pySig.pad(2048) Scale = 1024; print "Starting" tol = [1]; parallelProjections.initialize_plans(np.array([Scale]),np.array(tol)) classicBlock = mdct_block.Block(Scale,pySig, 0, debugLevel=3,useC=True) setBlock = joint_block.SetBlock(Scale,[pySig], debugLevel=3,useC=True) # compute the projections, should be equivalent classicBlock.update(pySig, 0, -1) setBlock.update([pySig], [0], [-1]) maxClassicAtom1 = classicBlock.getMaxAtom(); print maxClassicAtom1.length , maxClassicAtom1.frame print maxClassicAtom1.frequencyBin , maxClassicAtom1.mdct_value # plt.figure() # plt.plot(classicBlock.projectionMatrix) # plt.plot(setBlock.projectionMatrix[:,0],'r:') # plt.show() maxSpreadcAtom1 = setBlock.getAdaptedBestAtoms(noAdapt=True)[0] print maxSpreadcAtom1.length , maxSpreadcAtom1.frame print maxSpreadcAtom1.frequencyBin, maxSpreadcAtom1.mdct_value # assert equality using the inner comparison method of MDCT atoms self.assertEqual(maxClassicAtom1 ,maxSpreadcAtom1 ) pySig.subtract(maxSpreadcAtom1); # recompute the projections classicBlock.update(pySig, 0, -1) setBlock.update([pySig], [0], [-1]) # plt.show() maxClassicAtom2 = classicBlock.getMaxAtom(); print maxClassicAtom2.length , maxClassicAtom2.frame , maxClassicAtom2.frequencyBin , maxClassicAtom2.mdct_value maxSpreadcAtom2 = setBlock.getAdaptedBestAtoms(noAdapt=True)[0] print maxSpreadcAtom2.length , maxSpreadcAtom2.frame , maxSpreadcAtom2.frequencyBin, maxSpreadcAtom2.mdct_value self.assertEqual(maxClassicAtom2 ,maxSpreadcAtom2 ) parallelProjections.clean_plans()
def symetryTest(self): """ Youpi""" pySig = signals.InitFromFile('../../../data/glocs.wav',forceMono=True,doNormalize=True); pySig2 = signals.InitFromFile('../../../data/voicemale.wav',forceMono=True,doNormalize=True); pySig3 = signals.InitFromFile('../../../data/voicefemale.wav',forceMono=True,doNormalize=True); pySig4 = signals.InitFromFile('../../../data/orchestra.wav',forceMono=True,doNormalize=True); decalage = 0; Start = 1.0; Stop = 1.5 pySig.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency); pySig2.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency); pySig3.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency); pySig4.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency); pySig2.dataVec += pySig.dataVec pySig3.dataVec += pySig.dataVec pySig4.dataVec += pySig.dataVec pySig2.pad(8192) pySig3.pad(8192) pySig4.pad(8192) # pySig3.pad(16384) dico = [128,1024,8192]; nbAtoms = 1; jointDico = joint_dico.SetDico(dico , selectNature='sum', tol=[2,2,2]); jointDicoNL = joint_dico.SetDico(dico , nonLinear = True, selectNature='penalized', tol=[2,2,2] , params=0); jointDico.initialize((pySig2,pySig3,pySig4)) parallelProjections.initialize_plans(np.array(jointDico.sizes), np.array(jointDico.tolerances)) jointDico.update((pySig2,pySig3,pySig4), 0, debug=2) plt.figure() # plt.subplot(211) # plt.plot([block.projectionMatrix for block in jointDico.blocks]) plt.plot(jointDico.blocks[2].bestScoreTree) jointDico.update((pySig3,pySig2,pySig4), 0, debug=2) # plt.subplot(212) # plt.plot([block.projectionMatrix for block in jointDico.blocks]) plt.plot(jointDico.blocks[2].bestScoreTree,'r:') plt.show() parallelProjections.clean_plans(np.array(jointDico.sizes))
def dicos(self): # create a SpreadDico pySig = signals.InitFromFile('../../../data/glocs.wav',forceMono=True); pySig2 = pySig.copy() decalage = 50; pySig.crop(0, 5*pySig.samplingFrequency); pySig2.crop(decalage, decalage + 5*pySig.samplingFrequency); pySig.pad(2048) pySig2.pad(2048) dico = [128,1024,8192]; tol = [2]*len(dico); parallelProjections.initialize_plans(np.array(dico),np.array(tol)) classicDIco = mdct_dico.Dico(dico, useC=True); DicoSet = joint_dico.SetDico(dico, useC=True) classicDIco.initialize(pySig) DicoSet.initialize((pySig,pySig2)) classicDIco.update(pySig, 2) DicoSet.update((pySig,pySig2), 2) classicAtom1 = classicDIco.getBestAtom(0) JointAtoms = DicoSet.getBestAtom(0) print JointAtoms # self.assertEqual(classicAtom1 ,JointAtom1 ) # pySig.subtract(classicAtom1); # classicDIco.update(pySig, 2) # spreadDico.update(pySig, 2) # # classicAtom2 = classicDIco.getBestAtom(0) # spreadAtom2 = spreadDico.getBestAtom(0) # # self.assertNotEqual(classicAtom2 ,spreadAtom2 ) parallelProjections.clean_plans()
import numpy as np from scipy.stats import gmean from cmath import exp, pi import matplotlib.pyplot as plt print "-----Test mp sur multi-echelle MDCT" mdctDico = [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384] tol = [2 for i in mdctDico] print "test the initialization function" if parallelProjections.initialize_plans(np.array(mdctDico), np.array(tol)) != 1: print "Initiliazing Stage Failed" if parallelProjections.clean_plans() != 1: print "Initiliazing Stage Failed" pySigOriginal = signals.InitFromFile("../../data/ClocheB.wav", True, True) pyDico2 = dico.Dico(mdctDico) pyDico_Lomp = dico.LODico(mdctDico) residualSignal = pySigOriginal.copy() app, decay = mp.mp(pySigOriginal, pyDico2, 20, 200, 0) print " profiling test with C integration" cProfile.runctx("mp.mp(pySigOriginal, pyDico2, 20, 200 ,0)", globals(), locals()) cProfile.runctx("mp.mp(pySigOriginal, pyDico_Lomp, 20, 200 ,0)", globals(), locals())
plt.plot(decayList[0],'r') plt.plot(decayList[1],'g') # plt.plot(decayList[2],'k') plt.figure(figsize=(16,8)) plt.subplot(121) approxSpecList[0].plotTF(ylim=[0,4000]) plt.title('Pattern 1') plt.subplot(122) approxSpecList[1].plotTF(ylim=[0,4000]) plt.title('Pattern 2 ') # plt.savefig('TestTFMasking.png') parallelProjections.clean_plans() def symetryTest(self): """ Youpi""" pySig = signals.InitFromFile('../../../data/glocs.wav',forceMono=True,doNormalize=True); pySig2 = signals.InitFromFile('../../../data/voicemale.wav',forceMono=True,doNormalize=True); pySig3 = signals.InitFromFile('../../../data/voicefemale.wav',forceMono=True,doNormalize=True); pySig4 = signals.InitFromFile('../../../data/orchestra.wav',forceMono=True,doNormalize=True); decalage = 0; Start = 1.0; Stop = 1.5 pySig.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency); pySig2.crop(Start*pySig.samplingFrequency, Stop*pySig.samplingFrequency);
def mp_joint( originalSignalList , dictionary , targetSRR , maxIteratioNumber , debug=0 , padSignal=True, escape = False, Threshold = 0.4, ThresholdMap = None, doEval=False, sources=None, interval=100, doClean = True, waitbar=True, noAdapt=False, silentFail=False): """ Joint Matching Pursuit : Takes a bunch of signals in entry and decomposes the common part out of them Gives The common model and the sparse residual for each signal in return """ # back compatibility - use debug levels now if debug is not None: _Logger.setLevel(debug) _Logger.info("Call to mp.mp_joint") # We now work on a list of signals: we have a list of approx and residuals residualSignalList = []; currentApproxList = []; resEnergyList = []; approxSRRList = []; if escape: escapeApproxList = []; escItList = []; criterions = []; # if doEval: # SDRs = []; # SIRs = []; # SARs = []; # dictionaryList = [] ThresholdDict = {}; if ThresholdMap is None: for size in dictionary.sizes: ThresholdDict[size] = Threshold; else: for size,value in zip(dictionary.sizes,ThresholdMap): ThresholdDict[size] = value; # create a mean approx of the background meanApprox = Approx.Approx(dictionary, [], originalSignalList[0], debugLevel=debug) k = 1; for originalSignal in originalSignalList: _Logger.debug("Initializing Signal Number " + str(k)) # if padSignal: # originalSignal.pad(dictionary.getN()) residualSignalList.append(originalSignal.copy()); # initialize approximant currentApproxList.append(Approx.Approx(dictionary, [], originalSignal, debugLevel=debug)); if escape: escapeApproxList.append(Approx.Approx(dictionary, [], originalSignal, debugLevel=debug)); escItList.append([]); # residualEnergy resEnergyList.append([]); approxSRRList.append(currentApproxList[-1].computeSRR()); k += 1; # initialize blocks using the first signal: they shoudl all have the same length _Logger.debug("Initializing Dictionary") dictionary.initialize(residualSignalList) # FFTW Optimization for C code: initialize module global variables try: if parallelProjections.initialize_plans(np.array(dictionary.sizes), np.array(dictionary.tolerances)) != 1: raise ValueError("Something failed during FFTW initialization step "); except: _Logger.error("Initialization step failed"); raise; iterationNumber = 0; approxSRR = max(approxSRRList); # Decomposition loop: stopping criteria is either SNR or iteration number while (approxSRR < targetSRR) & (iterationNumber < maxIteratioNumber): _Logger.info("mp LOOP : iteration " + str(iterationNumber+1)) # Compute inner products and selects the best atom dictionary.update( residualSignalList , iterationNumber ) if debug>0: maxScale = dictionary.bestCurrentBlock.scale maxFrameIdx = math.floor(dictionary.bestCurrentBlock.maxIdx / (0.5*maxScale)); maxBinIdx = dictionary.bestCurrentBlock.maxIdx - maxFrameIdx * (0.5*maxScale) _Logger.debug("It: "+ str(iterationNumber)+ " Selected atom "+str(dictionary.bestCurrentBlock.maxIdx)+" of scale " + str(maxScale) + " frequency bin " + str(maxBinIdx) + " value : " + str(dictionary.maxBlockScore) + " Frame : " + str(maxFrameIdx)); # retrieve the best correlated atoms, locally adapted to the signal bestAtomList = dictionary.getBestAtom(debug,noAdapt=noAdapt) ; if bestAtomList is None : print 'No atom selected anymore' raise ValueError('Failed to select an atom') escapeThisAtom = False; if escape: # Escape mechanism : if variance of amplitudes is too big : assign it to the biggest only mean = np.mean([abs(atom.getAmplitude()) for atom in bestAtomList]) std = np.std([abs(atom.getAmplitude()) for atom in bestAtomList]) maxValue = np.max([abs(atom.getAmplitude()) for atom in bestAtomList]) _Logger.debug("Mean : " +str(mean)+" - STD : " + str(std)) criterions.append(std/mean) # print criterions[-1] if (std/mean) > ThresholdDict[atom.length]: escapeThisAtom = True; # print "Escaping Iteration ",iterationNumber,": mean " , mean , " std " , std _Logger.debug("Escaping!!") for sigIdx in range(len(residualSignalList)): if not escapeThisAtom: # add atom to current regular approx currentApproxList[sigIdx].addAtom(bestAtomList[sigIdx] , clean=False) dictionary.computeTouchZone(sigIdx ,bestAtomList[sigIdx]) # subtract atom from residual try: residualSignalList[sigIdx].subtract(bestAtomList[sigIdx] , debug) except ValueError: if silentFail: continue else: raise ValueError("Subtraction of atom failed") else: # Add this atom to the escape approx only if this signal is a maxima if abs(bestAtomList[sigIdx].getAmplitude()) == maxValue: # if True: # print "Added Atom to signal " + str(sigIdx) escapeApproxList[sigIdx].addAtom(bestAtomList[sigIdx]) currentApproxList[sigIdx].addAtom(bestAtomList[sigIdx]) escItList[sigIdx].append(iterationNumber); # subtract atom from residual residualSignalList[sigIdx].subtract(bestAtomList[sigIdx] , debug) dictionary.computeTouchZone(sigIdx ,bestAtomList[sigIdx] ) else: _Logger.debug("Atom not subtracted in this signal"); dictionary.computeTouchZone(sigIdx , bestAtomList[sigIdx]) # update energy decay curves resEnergyList[sigIdx].append(residualSignalList[sigIdx].energy) if debug>0 or (iterationNumber %interval ==0): approxSRRList[sigIdx] = currentApproxList[sigIdx].computeSRR(residualSignalList[sigIdx]) _Logger.debug("Local adaptation of atom "+str(sigIdx)+ " - Position : " + str(bestAtomList[sigIdx].timePosition) + " Amplitude : " + str(bestAtomList[sigIdx].projectionScore) + " TimeShift : " + str(bestAtomList[sigIdx].timeShift)) # if doClean and sigIdx>0: # del bestAtomList[sigIdx].waveform; # also add the mean atom to the background model UNLESS this is an escaped atom if not escapeThisAtom: # meanApprox.addAtom(bestAtomList[0] ) meanApprox.addAtom(dictionary.getMeanAtom(getFirstAtom=False) , clean=doClean) _Logger.debug("Atom added to common rep "); if doClean: for sigIdx in range(len(residualSignalList)): del bestAtomList[sigIdx].waveform; # dictionary.computeTouchZone() # approxSRR = currentApprox.computeSRR(); _Logger.debug("SRRs reached of " + str(approxSRRList) + " at iteration " + str(iterationNumber)) # if doEval and ( (iterationNumber+1) % interval ==0): # estimSources = np.zeros(sources.shape) # # first estim the source for the common part # estimSources[0, :,0] = meanApprox.recomposedSignal.dataVec # # for sigIdx in range(len(residualSignalList)): ## estimSources[sigIdx+1, :,0] = currentApproxList[sigIdx].recomposedSignal.dataVec + escapeApproxList[sigIdx].recomposedSignal.dataVec; # estimSources[sigIdx+1, :,0] = escapeApproxList[sigIdx].recomposedSignal.dataVec; # [SDR,ISR,SIR,SAR] = bss_eval_images_nosort(estimSources,sources) # ## print SDR , SIR # SDRs.append(SDR) # SIRs.append(SIR) # SARs.append(SAR) # ## print approxSRRList iterationNumber += 1; if (iterationNumber %interval ==0): print iterationNumber print [resEnergy[-1] for resEnergy in resEnergyList] # VERY IMPORTANT CLEANING STAGE! if parallelProjections.clean_plans(np.array(dictionary.sizes)) != 1: raise ValueError("Something failed during FFTW cleaning stage "); # if waitbar and (iterationNumber %(maxIteratioNumber/100) ==0): # print float(iterationNumber)/float(maxIteratioNumber/100) , "%", if not escape: return meanApprox, currentApproxList, resEnergyList , residualSignalList else: # time to add the escaped atoms to the corresponding residuals: # for sigIdx in range(len(residualSignalList)): # residualSignalList[sigIdx].dataVec += escapeApproxList[sigIdx].recomposedSignal.dataVec; # if doEval: # return meanApprox, currentApproxList, resEnergyList , residualSignalList , escapeApproxList , criterions , SDRs, SIRs , SARs return meanApprox, currentApproxList, resEnergyList , residualSignalList , escapeApproxList , escItList
def mp( originalSignal , dictionary , targetSRR , maxIteratioNumber , debug=0 , padSignal=True , itClean=False , silentFail=False, plot = False, debugSpecific=-1, cutBorders=False): """Common Matching Pursuit Loop Options are detailed below: Args: `originalSignal`: the original signal (as a :class:`.Signal` object) :math:`x` to decompose `dictionary`: the dictionary (as a :class:`.Dico` object) :math:`\Phi` on which to decompose :math:x `targetSRR`: a target Signal to Residual Ratio `maxIteratioNumber`: maximum number of iteration allowed Returns: `approx`: A :class:`.Approx` object encapsulating the approximant `decay`: A list of residual's energy across iterations Example:: >>> approx,decay = mp.mp(x, D, 10, 1000) For decomposing the signal x on the Dictionary D at either SRR of 10 dB or using 1000 atoms: x must be a :class:`.Signal` and D a :class:`.Dico` object """ # back compatibility - use debug levels now if debug is not None: _Logger.setLevel(debug) # optional add zeroes to the edge if padSignal: originalSignal.pad(dictionary.getN()) residualSignal = originalSignal.copy(); # FFTW Optimization for C code: initialize module global variables try: if parallelProjections.initialize_plans(np.array(dictionary.sizes), np.array([2 for i in dictionary.sizes])) != 1: raise ValueError("Something failed during FFTW initialization step "); except: _Logger.error("Initialization step failed"); raise; # initialize blocks dictionary.initialize(residualSignal) # initialize approximant currentApprox = Approx.Approx(dictionary, [], originalSignal, debugLevel=debug); # residualEnergy resEnergy = [] iterationNumber = 0; approxSRR = currentApprox.computeSRR(); # check if signal has null energy if residualSignal.energy == 0: _Logger.info(" Null signal energy ") return currentApprox , resEnergy resEnergy.append(residualSignal.energy) if plot: plt.ion() fig = plt.figure() ax1 = plt.subplot(211); ax2 = plt.subplot(212); # Decomposition loop: stopping criteria is either SNR or iteration number while (approxSRR < targetSRR) & (iterationNumber < maxIteratioNumber): maxBlockScore = 0; bestBlock = None; if (iterationNumber ==debugSpecific): debug=3; _Logger.setLevel(3) # Compute inner products and selects the best atom dictionary.update(residualSignal , iterationNumber ) # retrieve the best correlated atom bestAtom = dictionary.getBestAtom(debug) ; if bestAtom is None : print 'No atom selected anymore' return currentApprox , resEnergy if debug>0: # TODO reformulate for both 1D and 2D _Logger.debug("It: "+ str(iterationNumber)+ " Selected atom "+str(dictionary.bestCurrentBlock.maxIdx)+" of scale " + str(bestAtom.length) + " frequency bin " + str(bestAtom.frequencyBin) + " at " + str(bestAtom.timePosition) + " value : " + str(bestAtom.getAmplitude()) + " time shift : " + str(bestAtom.timeShift) + " Frame : " + str(bestAtom.frame)); # + " K = " + str(np.sqrt(bestAtom.mdct_value**2 / residualSignal.energy))) if bestAtom.phase is not None: _Logger.debug(' phase of : ' + str(bestAtom.phase)); try: residualSignal.subtract(bestAtom , debug) dictionary.computeTouchZone(bestAtom) except ValueError: if not silentFail: _Logger.error("Something wrong happened at iteration " + str(iterationNumber) + " atom substraction abandonned") # TODO refactoring print "Atom scale : " , bestAtom.length ," , frequency Bin: " ,bestAtom.frequencyBin," , location : " ,bestAtom.timePosition, " ,Time Shift : " ,bestAtom.timeShift , " , value : " , bestAtom.getAmplitude(); if debug>1: plt.figure() plt.plot(residualSignal.dataVec[bestAtom.timePosition : bestAtom.timePosition + bestAtom.length ]) plt.plot(bestAtom.waveform) plt.plot(residualSignal.dataVec[bestAtom.timePosition : bestAtom.timePosition + bestAtom.length ] - bestAtom.waveform , ':') plt.legend(('Signal' , 'Atom substracted', 'residual')) plt.title('Iteration ' + str(iterationNumber)) dictionary.bestCurrentBlock.plotScores() plt.show() return currentApprox , resEnergy if debug>1: _Logger.debug("new residual energy of " + str(sum(residualSignal.dataVec **2))) if not cutBorders: resEnergy.append(residualSignal.energy) else: # only compute the energy without the padded borders wher eventually energy has been created padd = 256; # assume padding is max dictionaty size resEnergy.append(np.sum(residualSignal.dataVec[padd:-padd]**2)) # add atom to dictionary currentApprox.addAtom(bestAtom , dictionary.bestCurrentBlock.getWindow()) # compute new SRR and increment iteration Number approxSRR = currentApprox.computeSRR(residualSignal); if plot: ax1.clear() # plt.subplot(121) plt.title('Iteration : ' + str(iterationNumber) + ' , SRR : ' + str(approxSRR)) ax1.plot(currentApprox.recomposedSignal.dataVec) ax2.clear() plt.draw() _Logger.debug("SRR reached of " + str(approxSRR) + " at iteration " + str(iterationNumber)) iterationNumber += 1; # cleaning if itClean: del bestAtom.waveform # VERY IMPORTANT CLEANING STAGE! if parallelProjections.clean_plans(np.array(dictionary.sizes)) != 1: raise ValueError("Something failed during FFTW cleaning stage "); # end of loop output the approximation and the residual energies if plot: plt.ioff() return currentApprox , resEnergy
def OMP( originalSignal , dictionary , targetSRR , maxIteratioNumber , debug=0 , padSignal=True , itClean=False ): # EXPERIMENTAL: NOT TESTED! AND DEPRECATED USE AT YOUR OWN RISKS # Orthogonal Matching Pursuit Loop """ # back compatibility - use debug levels now if not debug: debug =0; # optional add zeroes to the edge if padSignal: originalSignal.pad(dictionary.getN()) residualSignal = originalSignal.copy(); # FFTW C code optimization if parallelProjections.initialize_plans(np.array(dictionary.sizes)) != 1: raise ValueError("Something failed during FFTW initialization step "); # initialize blocks dictionary.initialize(residualSignal) # initialize approximant currentApprox = Approx.Approx(dictionary, [], originalSignal); # residualEnergy resEnergy = [] iterationNumber = 0; approxSRR = currentApprox.computeSRR(); # projMatrix = np.zeros((originalSignal.length,1)) projMatrix = [] atomKeys = []; # loop is same as mp except for orthogonal projection of the atom on the residual while (approxSRR < targetSRR) & (iterationNumber < maxIteratioNumber): maxBlockScore = 0; bestBlock = None; # Compute inner products and selects the best atom dictionary.update(residualSignal , iterationNumber) bestAtom = dictionary.getBestAtom(debug ) ; if bestAtom is None : print 'No atom selected anymore' return currentApprox , resEnergy if debug>0: strO = ("It: "+ str(iterationNumber)+ " Selected atom of scale " + str(bestAtom.length) + " frequency bin " + str(bestAtom.frequencyBin) + " at " + str(bestAtom.timePosition) + " value : " + str(bestAtom.mdct_value) + " time shift : " + str(bestAtom.timeShift)) print strO # need to recompute all the atoms projection scores to orthogonalise residual # approximate with moore-penrose inverse # add atom to projection matrix vec1 = np.concatenate( (np.zeros((bestAtom.timePosition,1)) , bestAtom.waveform.reshape(bestAtom.length,1)/bestAtom.mdct_value )) vec2 = np.zeros((originalSignal.length - bestAtom.timePosition - bestAtom.length,1)) atomVec = np.concatenate( (vec1 , vec2) ) # atomVec = atomVec/math.sqrt(sum(atomVec**2)) atomKey = (bestAtom.length,bestAtom.timePosition,bestAtom.frequencyBin); if iterationNumber>0: if atomKey not in atomKeys: projMatrix = np.concatenate((projMatrix , atomVec) , axis=1) atomKeys.append(atomKey) else: projMatrix = atomVec; atomKeys.append(atomKey) # Orthogonal projection via pseudo inverse calculation ProjectedScores = np.dot(np.linalg.pinv(projMatrix),originalSignal.dataVec.reshape(originalSignal.length,1)) # update residual currentApprox.recomposedSignal.dataVec = np.dot(projMatrix, ProjectedScores)[:,0] residualSignal.dataVec = originalSignal.dataVec - currentApprox.recomposedSignal.dataVec # # add atom to dictionary # currentApprox.addAtom(bestAtom , dictionary.bestCurrentBlock.wLong) # # for atom,i in zip(currentApprox.atoms , range(currentApprox.atomNumber)): # atom.projectionScore = ProjectedScores[i]; # atom.waveform = (ProjectedScores[i]/math.sqrt(sum(atom.waveform**2))) * atom.waveform; # residualSignal.subtract(bestAtom , debug) # dictionary.computeTouchZone(bestAtom) resEnergy.append(np.dot(residualSignal.dataVec.T ,residualSignal.dataVec )) recomposedEnergy = np.dot(currentApprox.recomposedSignal.dataVec.T , currentApprox.recomposedSignal.dataVec); # compute new SRR and increment iteration Number approxSRR = 10*math.log10( recomposedEnergy/ resEnergy[-1] ) # approxSRR = currentApprox.computeSRR(); if debug>0: print "SRR reached of " , approxSRR , " at iteration " , iterationNumber iterationNumber += 1; # cleaning if itClean: del bestAtom.waveform # VERY IMPORTANT CLEANING STAGE! if parallelProjections.clean_plans(np.array(dictionary.sizes)) != 1: raise ValueError("Something failed during FFTW cleaning stage "); return currentApprox , resEnergy
def mp_continue(currentApprox , originalSignal , dictionary , targetSRR , maxIteratioNumber , debug=0 , padSignal=True ): """ routine that restarts a decomposition from an existing, incomplete approximation """ if not isinstance(currentApprox, Approx.Approx): raise TypeError("provided object is not a py_pursuit_Approx"); # optional add zeroes to the edge if padSignal: originalSignal.pad(dictionary.getN()) residualSignal = originalSignal.copy(); # retrieve approximation from residual if currentApprox.recomposedSignal is not None: residualSignal.dataVec -= currentApprox.recomposedSignal.dataVec residualSignal.energy = sum(residualSignal.dataVec**2); else: for atom in currentApprox.atoms: residualSignal.subtract(atom, debug) try: if parallelProjections.initialize_plans(np.array(dictionary.sizes), np.array([2 for i in dictionary.sizes])) != 1: raise ValueError("Something failed during FFTW initialization step "); except: _Logger.error("Initialization step failed"); raise; # initialize blocks dictionary.initialize(residualSignal) # residualEnergy resEnergy = [residualSignal.energy] iterationNumber = 0; approxSRR = currentApprox.computeSRR(); while (approxSRR < targetSRR) & (iterationNumber < maxIteratioNumber): maxBlockScore = 0; bestBlock = None; # Compute inner products and selects the best atom dictionary.update(residualSignal) # new version - also computes the waveform by inverse mdct # new version - also computes max cross correlation and adjust atom's waveform timeshift bestAtom = dictionary.getBestAtom(debug) if bestAtom is None : print 'No atom selected anymore' return currentApprox , resEnergy if debug>0: strO = ("It: "+ str(iterationNumber)+ " Selected atom of scale " + str(bestAtom.length) + " frequency bin " + str(bestAtom.frequencyBin) + " at " + str(bestAtom.timePosition) + " value : " + str(bestAtom.mdct_value) + " time shift : " + str(bestAtom.timeShift)) print strO try: residualSignal.subtract(bestAtom , debug) dictionary.computeTouchZone(bestAtom) except ValueError: print "Something wrong happened at iteration " ,iterationNumber , " atom substraction abandonned" if debug>1: plt.figure() plt.plot(residualSignal.dataVec[bestAtom.timePosition : bestAtom.timePosition + bestAtom.length ]) plt.plot(bestAtom.waveform) plt.plot(residualSignal.dataVec[bestAtom.timePosition : bestAtom.timePosition + bestAtom.length ] - bestAtom.waveform , ':') plt.legend(('Signal' , 'Atom substracted', 'residual')) plt.show() approxPath = "currentApprox_failed_iteration_" + str(iterationNumber) + ".xml" signalPath = "currentApproxRecomposedSignal_failed_iteration_" + str(iterationNumber) + ".wav" currentApprox.writeToXml(approxPath) currentApprox.recomposedSignal.write(signalPath) print " approx saved to " , approxPath print " recomposed signal saved to " , signalPath return currentApprox , resEnergy if debug>1: plt.figure() plt.plot(originalSignal.dataVec) plt.plot(residualSignal.dataVec , '--') plt.legend(("original", "residual at iteration " + str(iterationNumber))) plt.show() if debug>0: print "new residual energy of " , sum(residualSignal.dataVec **2) # BUGFIX? resEnergy.append(residualSignal.energy) # resEnergy.append(sum(residualSignal.dataVec **2)) # add atom to dictionary currentApprox.addAtom(bestAtom , dictionary.bestCurrentBlock.wLong) # compute new SRR and increment iteration Number # approxSRR = currentApprox.computeSRR(residualSignal); approxSRR = currentApprox.computeSRR(); iterationNumber += 1; if debug>0: print "SRR reached of " , approxSRR , " at iteration " , iterationNumber # cleaning del bestAtom.waveform # VERY IMPORTANT CLEANING STAGE! if parallelProjections.clean_plans(np.array(dictionary.sizes)) != 1: raise ValueError("Something failed during FFTW cleaning stage "); return currentApprox , resEnergy