samer@0: /* samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London. samer@0: * All rights reserved. samer@0: * samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY; samer@0: * without even the implied warranty of MERCHANTABILITY or samer@0: * FITNESS FOR A PARTICULAR PURPOSE. samer@0: */ samer@0: samer@0: package samer.models; samer@0: import samer.core.*; samer@0: import samer.core.types.*; samer@0: import samer.tools.*; samer@0: import samer.maths.*; samer@0: import samer.maths.*; samer@0: import samer.maths.opt.*; samer@0: samer@0: public class NoisyICA extends NamedTask implements Model samer@0: { samer@0: Vec x; // data (input) samer@0: int n, m; // sizes (data, sources) samer@0: Matrix A; // basis matrix samer@0: Model Ms, Me; // source and noise models samer@0: VVector s, z, e; // sources, reconstruction, error samer@0: VDouble E; // energy samer@0: samer@0: Task inference=new NullTask(); samer@0: samer@0: samer@0: // ----- variables used in computations ----------------- samer@0: samer@0: private double [] e_; samer@0: private double [] x_; samer@0: private double [] z_; samer@0: private double [] s_; samer@0: private VectorFunctionOfVector tA, tAt; samer@0: samer@0: samer@0: public NoisyICA(Vec in,int outs) { this(new Node("noisyica"),in.size(),outs); setInput(in); } samer@0: public NoisyICA(int ins,int outs) { this(new Node("noisyica"),ins,outs); } samer@0: public NoisyICA(Node node, int inputs, int outputs) samer@0: { samer@0: super(node); samer@0: Shell.push(node); samer@0: samer@0: n = inputs; samer@0: m = outputs; samer@0: samer@0: s = new VVector("s",m); samer@0: z = new VVector("z",n); samer@0: e = new VVector("e",n); samer@0: E = new VDouble("E"); samer@0: A = new Matrix("A",n,m); samer@0: A.identity(); samer@0: samer@0: e_ = e.array(); samer@0: z_ = z.array(); samer@0: s_ = s.array(); samer@0: tA = new MatrixTimesVector(A); samer@0: tAt= new MatrixTransposeTimesVector(A); samer@0: samer@0: Shell.pop(); samer@0: } samer@0: samer@0: public Model getSourceModel() { return Ms; } samer@0: public Model getNoiseModel() { return Me; } samer@0: public void setSourceModel(Model m) { Ms=m; Ms.setInput(s); } samer@0: public void setNoiseModel(Model m) { Me=m; Me.setInput(e); } samer@0: public void setInput(Vec in) { x=in; x_ = x.array(); } samer@0: public Matrix basisMatrix() { return A; } samer@0: public VVector output() { return s; } samer@0: public VVector error() { return e; } samer@0: public VVector reconstruction() { return z; } samer@0: samer@0: public int getSize() { return n; } samer@0: samer@0: public void setInferenceTask(Task t) { inference=t; } samer@0: samer@0: public void infer() { samer@0: try { inference.run(); } samer@0: catch (Exception ex) { samer@0: Shell.trace("error: "+ex); samer@0: ex.printStackTrace(); samer@0: throw new Error("inference failed: "+ex); } samer@0: tA.apply(s_,z_); Mathx.sub(e_,x_,z_); samer@0: e.changed(); z.changed(); s.changed(); samer@0: } samer@0: samer@0: public void compute() { samer@0: E.set(Me.getEnergy() + Ms.getEnergy()); samer@0: // what about dE/dx? samer@0: } samer@0: public double getEnergy() { return E.value; } samer@0: public double [] getGradient() { return null; } // this is wrong samer@0: samer@0: /** get basis vector norms into given array */ samer@0: public void norms(double [] na) samer@0: { samer@0: double [][] M=A.getArray(); samer@0: samer@0: Mathx.zero(na); samer@0: for (int i=0; it || s<-t; } samer@0: }