Пример #1
0
    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()
Пример #2
0
    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))
Пример #3
0
    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()
Пример #4
0
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())
Пример #5
0
        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);
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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