/* SegmentReconstructionProvider.java created 2008-03-03 * */ package org.signalml.domain.book; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import org.signalml.util.Util; import pl.edu.fuw.MP.WignerMap.WignerMap; /** SegmentReconstructionProvider * * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. * (based on code by Dobieslaw Ircha) */ public class SegmentReconstructionProvider { private StandardBookSegment segment; private HashMap<StandardBookAtom, double[]> reconstructionMap; private double[][] atomReconstructions; private int width; private double[] fullReconstruction; private LinkedHashSet<StandardBookAtom> reconstruction = new LinkedHashSet<StandardBookAtom>(); private double[] selectiveReconstruction; private boolean selectiveReconstructionDirty; public SegmentReconstructionProvider() { } private void clear() { fullReconstruction = null; selectiveReconstruction = null; atomReconstructions = null; reconstructionMap = null; if (!reconstruction.isEmpty()) { if (segment == null) { reconstruction.clear(); } else { LinkedHashSet<StandardBookAtom> newReconstruction = new LinkedHashSet<StandardBookAtom>(); int atomCount = segment.getAtomCount(); StandardBookAtom atom; for (int i=0; i<atomCount; i++) { atom = segment.getAtomAt(i); if (reconstruction.contains(atom)) { newReconstruction.add(atom); } } reconstruction = newReconstruction; } } } public StandardBookSegment getSegment() { return segment; } public void setSegment(StandardBookSegment segment) { if (this.segment != segment) { this.segment = segment; clear(); } } public void setSegmentWithNaturalWidth(StandardBookSegment segment, float samplingFrequency) { if (this.segment != segment) { this.segment = segment; if (segment != null) { if (segment.hasSignal()) { width = segment.getSignalSamples().length; } else { width = (int)(segment.getSegmentTimeLength() * samplingFrequency); } } else { width = 16; } clear(); } } public int getWidth() { return width; } public void setWidth(int width) { if (this.width != width) { this.width = width; clear(); } } public int getAtomCount() { if (segment == null) { return 0; } return segment.getAtomCount(); } public double[] getAtomReconstructionAt(int index) { if (atomReconstructions == null) { if (segment == null) { atomReconstructions = new double[0][width]; } else { int atomCount = segment.getAtomCount(); atomReconstructions = new double[atomCount][width]; double ptr[] = new double[atomCount * width]; int i,itmp; int DimBase = segment.getSegmentLength(); double tmpsig[]=new double[DimBase+1],sum; double Exp[]=new double[DimBase],Cos[]=new double[DimBase]; for (int kk = 0; kk < atomCount; kk++) { StandardBookAtom atom = segment.getAtomAt(kk); ptr = atomReconstructions[kk]; if (atom.getType() == StandardBookAtom.DIRACDELTA_IDENTITY) { itmp=atom.getPosition(); if (atom.getAmplitude()<0f) { ptr[itmp] = -(double) atom.getModulus(); } else { ptr[itmp] = atom.getModulus(); } } else if (atom.getType() == StandardBookAtom.SINCOSWAVE_IDENTITY) { double freq = Math.PI * 2 * atom.getNaturalFrequency() / atom.getBaseLength(), phase = atom.getPhase() - freq * atom.getPosition(); for (i = 0, sum = 0.0; i < DimBase; i++) { sum += Util.sqr(tmpsig[i] = Math.cos(freq * i + phase)); } sum = atom.getModulus() / Math.sqrt(sum); for (i = 0; i < DimBase; i++) { ptr[i] = (tmpsig[i] * sum); } } else { double freq = Math.PI * 2 * atom.getNaturalFrequency() / atom.getBaseLength(), phase = atom.getPhase() - freq * atom.getPosition(); int start = 0, stop = DimBase - 1; WignerMap.MakeExpTable(Exp, Math.PI / Util.sqr(atom.getScale()), atom.getPosition(), start, stop); WignerMap.makeCosTable(Cos, start, stop, freq, phase); for (i = start, sum = 0.0; i <= stop; i++) sum += Util.sqr(tmpsig[i] = Exp[i] * Cos[i]); /* Math.cos(freq*i+phase) */ sum = atom.getModulus() / Math.sqrt(sum); for (i = start; i <= stop; i++) { ptr[i] = (tmpsig[i] * sum); } } } } } return atomReconstructions[index]; } public double[] getFullReconstruction() { if (fullReconstruction == null) { fullReconstruction = new double[width]; if (segment != null) { int count = segment.getAtomCount(); double[] atom; int i; int e; for (i=0; i<count; i++) { atom = getAtomReconstructionAt(i); for (e=0; e<width; e++) { fullReconstruction[e] += atom[e]; } } } } return fullReconstruction; } public HashMap<StandardBookAtom, double[]> getReconstructionMap() { if (reconstructionMap == null) { int atomCount = getAtomCount(); reconstructionMap = new HashMap<StandardBookAtom, double[]>(atomCount); for (int i=0; i<atomCount; i++) { reconstructionMap.put(segment.getAtomAt(i), getAtomReconstructionAt(i)); } } return reconstructionMap; } public void clearSelectiveReconstruction() { reconstruction.clear(); selectiveReconstructionDirty = true; } public int getSelectiveReconstructionSize() { return reconstruction.size(); } public boolean isAtomInSelectiveReconstruction(int index) { if (this.getAtomCount() > index) return reconstruction.contains(segment.getAtomAt(index)); else return false; } public boolean isAtomInSelectiveReconstruction(StandardBookAtom atom) { return reconstruction.contains(atom); } public void addAtomToSelectiveReconstruction(int index) { boolean added = reconstruction.add(segment.getAtomAt(index)); if (added && selectiveReconstruction != null && !selectiveReconstructionDirty) { // incrementally add double[] atom = getAtomReconstructionAt(index); for (int i=0; i<width; i++) { selectiveReconstruction[i] += atom[i]; } } else { selectiveReconstructionDirty = true; } } public void removeAtomFromSelectiveReconstruction(int index) { boolean removed = reconstruction.remove(segment.getAtomAt(index)); if (removed) { selectiveReconstructionDirty = true; } } public Iterator<StandardBookAtom> selectiveReconstructionInterator() { return reconstruction.iterator(); } public double[] getSelectiveReconstruction() { boolean zero = true; if (selectiveReconstruction == null) { selectiveReconstruction = new double[width]; selectiveReconstructionDirty = true; zero = false; } if (selectiveReconstructionDirty) { if (zero) { Arrays.fill(selectiveReconstruction, 0); } if (segment != null) { double[] atom; int e; HashMap<StandardBookAtom,double[]> map = getReconstructionMap(); Iterator<StandardBookAtom> it = reconstruction.iterator(); while (it.hasNext()) { atom = map.get(it.next()); for (e=0; e<width; e++) { selectiveReconstruction[e] += atom[e]; } } } } return selectiveReconstruction; } }