samer@0: /* samer@0: * Copyright (c) 2002, 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: samer@0: import samer.core.*; samer@0: import samer.core.types.*; samer@0: import samer.maths.*; samer@0: import samer.maths.opt.*; samer@0: import samer.tools.*; samer@0: samer@0: /** samer@0: Differential scaler: scales and offsets each element of a vector samer@0: independently aiming to match a given prior model. This is samer@0: like ICA using a diagonal weight matrix, with a 'zero-mean' samer@0: normalisation built in, though it doesn't actually the mean to samer@0: do this, but some statistic based on the prior model. samer@0: */ samer@0: samer@0: public class DiffScaler extends AnonymousTask implements Model samer@0: { samer@0: private Model M; // models P(s) samer@0: private int n; samer@0: private Vec x; samer@0: private VVector s; samer@0: private VVector w; // vector of multipliers samer@0: private VVector mu; // vector of offsets samer@0: private VDouble logA; samer@0: samer@0: double [] _x, _s, _g, _w, _m, phi; samer@0: samer@0: public DiffScaler( Vec input, Model M) { this(input); setOutputModel(M); M.setInput(s); } samer@0: public DiffScaler( Vec input) { this(input.size()); setInput(input); } samer@0: public DiffScaler( int N) samer@0: { samer@0: n = N; samer@0: samer@0: x = null; samer@0: mu = new VVector("mu",n); mu.addSaver(); samer@0: w = new VVector("w",n); w.addSaver(); samer@0: s = new VVector("output",n); samer@0: logA = new VDouble("log|A|"); samer@0: samer@0: _s = s.array(); samer@0: _w = w.array(); samer@0: _m = mu.array(); samer@0: _g = new double[n]; samer@0: phi = null; samer@0: reset(); samer@0: } samer@0: samer@0: public int getSize() { return n; } samer@0: public VVector output() { return s; } samer@0: public VVector weights() { return w; } samer@0: public VVector offsets() { return mu; } samer@0: public Model getOutputModel() { return M; } samer@0: public void setOutputModel(Model m) { M=m; } samer@0: public void setInput(Vec in) { x=in; _x=x.array(); } samer@0: public void reset() { reset(1.0); } samer@0: public void reset(double k) { samer@0: Mathx.setAll(_w,k); w.changed(); samer@0: Mathx.setAll(_m,0); mu.changed(); samer@0: logA.set(-sumlog(_w)); samer@0: } samer@0: samer@0: public String toString() { return "DiffScaler("+x+")"; } samer@0: private static double sumlog(double [] x) { samer@0: double S=0; samer@0: for (int i=0; ithresh) return; samer@0: double [] phi=M.getGradient(); samer@0: for (int i=0; i0; i--) { samer@0: G[i] -= T*(lw[i-1] -2*lw[i]+lw[i+1]); samer@0: } samer@0: samer@0: // do the same for H? samer@0: // may have to modify T. samer@0: H[0] -= T*(_m[1]-_m[0]); i=n-1; samer@0: H[i] -= T*(_m[i-1]-_m[i]); i--; samer@0: for (; i>0; i--) { samer@0: H[i] -= T*(_m[i-1] -2*_m[i]+_m[i+1]); samer@0: } samer@0: samer@0: super.flush(); samer@0: } samer@0: samer@0: public void dispose() { tension.dispose(); super.dispose(); } samer@0: } samer@0: } samer@0: