view src/samer/maths/VVector.java @ 5:b67a33c44de7

Remove some crap, etc
author samer
date Fri, 05 Apr 2019 21:34:25 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	VVector.java
 *
 *	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.core.util.*;
import  samer.tools.*;
import  java.awt.*;
import  java.awt.event.*;
import  java.util.*;
import  java.io.*;
/**
	A Viewable Vec. The default viewer displays only
	the name and size of the vector, but the attached
	Agent allows creation of other types of viewer.
  */

public class VVector extends Viewable implements Vec, Agent, Saveable
{
	Vec	vec;

	protected VVector() {}

	public VVector(Node node, Vec v) {
		super(node); vec=v; setAgent(this);
		Shell.registerViewable(this);
	}

	public VVector(Node node, double [] x) { this(node,new Vec.ForArray(x)); }
	public VVector(String nm, double [] x) { this(new Node(nm), x); }
	public VVector(String nm, int n) { this(new Node(nm), n); }
	public VVector(Node node, int n) {
		this(node,new Vec.ForArray(new double[n]));
	}

	public void addSaver() { addAgent(new Saver(this,getNode())); }

	// Vec implementation
	public Iterator	iterator()	{ return vec.iterator(); }
	public int			size()		{ return vec.size(); }
	public Mat			mat()			{ return vec.mat(); }
	public double[]	array()		{ return vec.array(); }

	public Vec    getVec() { return vec; }
	public Viewer getViewer()
	{
		BaseViewer		vwr = new BaseViewer(this);
		StringBuffer	buf=new StringBuffer();

		buf.append(getLabel())
			.append(" (").append(vec.size())
			.append(")");
		vwr.setText(buf.toString());

		return vwr;
	}

	public void copyFrom(double[] y) { Mathx.copy(y,array()); changed(); }
	public void copyTo(double[] y) { Mathx.copy(array(),y); }
	// Saveable implementation
	public void save(OutputStream out) throws Exception {
		new ObjectOutputStream(out).writeObject(array());
	}

	public void load(InputStream in) throws Exception {
		Object o=new ObjectInputStream(in).readObject();
		Mathx.copy((double [])o,array()); 	changed();
	}

		/** Write the given Vec to a PrintWriter as one line of text,
		consisting of space delimited numbers. */

	public void write(Writer w) { print(new PrintWriter(w)); }
	public void print(PrintWriter prn) {
		Vec.Iterator i=vec.iterator();
		prn.print(i.next());
		while (i.more()) {
			prn.print(' ');
			prn.print(i.next());
		}
		prn.println();
		prn.flush();
	}

	/** Reads a line of numbers from the reader and stores in the Vec */
	public void read(Reader input) throws IOException
	{
		StreamTokenizer tok= new StreamTokenizer(new BufferedReader(input));

		/*
		a)	words are made from only +,-,.,e,E, or digits
		 b) if other tokens may exist in a line, these are ignored
		 c) if there is too much stuff on one line, the rest is discarded.
		 d) if there aren't enough numbers, throw an exception.
		 */

		tok.resetSyntax();
		tok.wordChars('+','+');
		tok.wordChars('-','-');
		tok.wordChars('0','9');
		tok.wordChars('.','.');
		tok.wordChars('e','e');
		tok.wordChars('E','E');
		tok.commentChar('#');
		tok.commentChar(';');
		tok.commentChar('%');
		tok.whitespaceChars(0, ' ');
		tok.eolIsSignificant(true);

      // Ignore initial empty lines
		while (tok.nextToken() == StreamTokenizer.TT_EOL);
		if (tok.ttype == StreamTokenizer.TT_EOF)
			throw new EOFException("EOF on vector read.");

		double [] x=vec.array();
		int			i=0;

		// get first x.length words and convert to numbers
		do {
			if (tok.ttype==StreamTokenizer.TT_WORD)
				x[i++]=Double.parseDouble(tok.sval);
		} while (tok.nextToken()!=StreamTokenizer.TT_EOL && i<x.length);
		// !! what if EOF?
		if (i<(x.length-1)) throw new IOException("not enough numbers");

		// now mop up rest of line
		while (tok.ttype!=StreamTokenizer.TT_EOL) tok.nextToken();
		changed();
	}

	public void getCommands(Registry r) {
		r.add("zeros").add("negate").add("set").group();
		r.add("plotter")
		 .add("image")
		 .add("reshaped image")
		 .add("trace")
		 .add("image editor")
		 .add("plotter editor")
		 .add("multitrace");
		r.group();
		r.add("publish");

	}

	private void expose(Viewer v) { Shell.expose(v,"window"); }

	public void execute(String cmd, Environment env) throws Exception
	{
		if (cmd.equals("zeros")) {

			double [] x = vec.array();
			if (x!=null) Mathx.zero(x);
			else {	// try using Mat interface instead
				Mat mat = vec.mat();
				if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,0);
				else throw new Exception("Vector inaccessible: "+getLabel());
			}
			changed();

		} else if (cmd.equals("set")) {

			double y=X._double(env.datum(),1);
			double [] x = vec.array();
			if (x!=null) Mathx.setAll(x,y);
			else {	// try using Mat interface instead
				Mat mat = vec.mat();
				if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,y);
				else throw new Exception("Vector inaccessible: "+getLabel());
			}
			changed();

		} else if (cmd.equals("negate")) {

			double [] x = vec.array();
			if (x!=null) Mathx.negate(x);
			else {	// try using Mat interface instead
				Mat mat = vec.mat();
				if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,-mat.get(1,i));
				else throw new Exception("Vector inaccessible: "+getLabel());
			}
			changed();

		} else if (cmd.equals("plotter")) {

			pushNode("plotter");
			expose(new VectorPlotter(this,getVec()));
			Shell.pop();

		} else if (cmd.equals("plotter editor")) {

			pushNode("editor.plotter");
			expose(new VectorEditor(this,getVec()));
			Shell.pop();

		} else if (cmd.equals("image")) {

			Node n=pushNode("image");
			expose(createVectorImage(n,vec.size(),1));
			Shell.pop();

		} else if (cmd.equals("reshaped image")) {

			Node n=pushNode("reshaped.image");
			int w=Shell.getInt("width",1);
			int h=Shell.getInt("height",vec.size());
			expose(createVectorImage( n, w, h));
			Shell.pop();

		} else if (cmd.equals("image editor")) {

			Node n=pushNode("editor.image");

			final Shell.Window win = Shell.getWindow("window");
			final ImageViewer vwr = createVectorImage(n,vec.size(),1);
			final MatEditor editor = new MatEditor(mat(),vwr,this,vwr);

			win.container().setLayout( new BorderLayout(6,6));
			win.container().add( vwr.getComponent(), "Center");
			// win.container().add( editor.setto.getViewer().getComponent(),"South");
			Shell.registerViewable(editor.setto);
			win.addWindowListener( new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					editor.detach();
					vwr.detach();
					win.dispose();
				}
			} );
			win.expose();

			// vwr.exposeCommands(this);

			Shell.pop();

		} else if (cmd.equals("trace")) {

			Node node=pushNode("trace");
			ImageSourceBase imgsrc=createImageSource(1,vec.size());
			expose(new ImageTrace(imgsrc,this));
			Shell.pop();

		} else if (cmd.equals("multitrace")) {

			Node node=pushNode("trace");
			expose(new VectorTraceObs(this,node));
			Shell.pop();
		} else if (cmd.equals("publish")) {
			Shell.put(X.string(env.datum(),node.fullName()),this);
		}
	}


	private Node pushNode(String nm) {
		Node n=new Node(nm,getNode());
		Shell.push(n);
		return n;
	}

	private ImageSourceBase createImageSource(int w, int h)
	{
		// this chooses an ImageSource depending on
		// the capabilities of the Vec
		double [] array=array();

		if (array!=null) {
			if (w>1) return new ArrayImageSource(array,w,h);
			else     return new ArrayVImageSource(array);
		} else {
			return new IteratorImageSource(getVec(),w,h);
		}
	}

	private ImageViewer createVectorImage( final Node n, int w, int h)
	{

		/*
			The VImageViewer handles displaying the image of
			a supplied ImageSource, but this object handles
			scaling of the colour map to match the range of
			values in a Vec, accessed by iterator rather than
			array.
		  */
		return new ImageViewer( createImageSource(w,h), this) {
			public void scale()
			{
				Vec.Iterator	i=vec.iterator();
				double			max, min, x;

				min=max=i.next();
				while (i.more()) {
					x=i.next();
					if (x>max) max=x;
					if (x<min) min=x;
				}

				getVMap().setDomain(min,max);
				getVMap().changed(this);
			}
		};
	}
}


class VectorTraceObs extends VectorTrace implements Observer {
	Observable obs;
	Node		node;

	VectorTraceObs(VVector v, Node n) {
		super(v);
		obs=v;
		node=n;
	}

	public void attach() {	super.attach(); obs.addObserver(this); }
	public void detach() {	obs.deleteObserver(this); super.detach(); }
	public void update(Observable o, Object arg)
	{
		if (o==obs) {
			if (arg==Viewable.DISPOSING) {
				Shell.releaseViewer(this);
			} else {
				try { run(); }
				catch (Exception ex) {}
			}
		} else super.update(o,arg);
	}
}