view src/samer/maths/Ops.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
line wrap: on
line source
/*
 *	Copyright (c) 2000, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS iS and WITHOUT ANY WARRANTY; 
 *	without even the implied warranty of MERCHANTABILITY or 
 *	FITNESS FOR A PARTICULAR PURPOSE.
 */

package	samer.maths;
import	samer.core.*;
import	samer.tools.*;
import	java.util.*;


/**
	An agent which allows the creation of vectors and
	matrices, and can also arrange for them to be
	multiplied as part of the current task list
 */

public class Ops
{
	public static Task update(final Viewable v) {
		return new AnonymousTask() { public void run() { v.changed(); } };
	}

	public static Task times(VVector out, Matrix A, VVector x) {
		return new MatrixTimesVector(out,A,x);
	}

	// copy as much as possible from one vector to another
	public static Task transfer(final Vec in, final Vec out) {
		final int len=Math.min(in.size(),out.size());
		double src[]=in.array();

		if (src!=null) 	return new ArrayCopy(src,0,out.array(),0,len);
		else 				return new IteratorCopy(in,out,len);
	}

	// copy a given range from one vector to another
	public static Task transfer(
		final Vec in, int inpos, final Vec out, int outpos, int len)
	{
		return new ArrayCopy(in.array(),inpos,out.array(),outpos,len);
	}

	// copy a listed elements to another vector
	public static Task transfer(final Vec in, final Vec out, final int[] elements) {
		return new AnonymousTask() {
			double [] dst=out.array();
			double [] src=in.array();
			int N=elements.length;
			public void run() {
				for (int i=0; i<N; i++) dst[i]=src[elements[i]];
			}
		};
	}

	public static Task apply(Vec vout, final Function f, Vec vin) {
		final double [] in = vin.array();
		final double [] out = vout.array();
		return new AnonymousTask() {
			Function fn=f;
			public void run() { fn.apply(in,out); }
			public void setFunction(Function fn) { this.fn=fn; }
		};
	}

	public static Task apply(final Function fn, Vec vin) {
		final double [] in = vin.array();
		return new AnonymousTask() {
			public void run() { fn.apply(in); }
		};
	}

	public static Task apply(final VVector vout, final VectorFunctionOfVector fn, VVector vin) {
		final double [] in = vin.array();
		final double [] out= vout.array();
		return new AnonymousTask() {
			public void run() { fn.apply(in,out); vout.changed(); }
		};
	}

	public static void apply( Function fn, Matrix A) {
		double _A[][]=A.getArray();
		int N=A.getRowDimension();
		for (int i=0; i<N; i++) fn.apply(_A[i]); 
		A.changed();
	}

	public static void apply( Function fn, Matrix B, Matrix A) {
		double _A[][]=A.getArray(),_B[][]=B.getArray();
		int N=A.getRowDimension();
		for (int i=0; i<N; i++) fn.apply(_B[i],_A[i]); 
		A.changed();
	}


	
	public static Task plusEquals(final VVector x, final VVector y) {
		final double [] _x=x.array(), _y=y.array();
		return new AnonymousTask() {
			public void run() { Mathx.add(_x,_y); x.changed(); }
		};
	}
	
	public static Task timesEquals(final VVector x, final VVector y) {
		final double [] _x=x.array(), _y=y.array();
		return new AnonymousTask() {
			public void run() { Mathx.mul(_x,_y); x.changed(); }
		};
	}

	public static Task apply(final VectorFunctionOfVector fn, final VVector vinout) {
		final double [] in = vinout.array();
		return new AnonymousTask() {
			public void run() { fn.apply(in); vinout.changed(); }
		};
	}

	/**
		causes a task to run whenever an observable changes
	 */
	public static void triggerTask( final Task task, Observable obs)
	{
		obs.addObserver( new Observer() {
			public void update(Observable o, Object a) { 
				if (a==Viewable.DISPOSING) {
					o.deleteObserver(this);
					task.dispose();
					return;
				}
				try { task.run(); }
				catch (Exception ex) {}
			}
		} );
	}

	public static class ArrayCopy extends NullTask {
		Object src, dst;
		int		i, j, n;
		public ArrayCopy(Object s, int spos, Object d, int dpos, int len) {
			src=s; dst=d; i=spos; j=dpos; n=len;
		}
		public void run() { System.arraycopy(src,i,dst,j,n);	}
	}

	public static class IteratorCopy extends NullTask {
		Vec	src, dst;
		int 	N;
		
		public IteratorCopy(Vec src, Vec dst, int N) {
			this.src=src; this.dst=dst; this.N=N;
		}
		
		public void run() {
			Vec.Iterator it=src.iterator();
			double	[] a=dst.array();
			for (int i=0; i<N; i++) a[i]=it.next();
		}
	}
}