samer@0: /* samer@0: * VVector.java 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.maths; samer@0: import samer.core.*; samer@0: import samer.core.util.*; samer@0: import samer.tools.*; samer@0: import java.awt.*; samer@0: import java.awt.event.*; samer@0: import java.util.*; samer@0: import java.io.*; samer@0: /** samer@0: A Viewable Vec. The default viewer displays only samer@0: the name and size of the vector, but the attached samer@0: Agent allows creation of other types of viewer. samer@0: */ samer@0: samer@0: public class VVector extends Viewable implements Vec, Agent, Saveable samer@0: { samer@0: Vec vec; samer@0: samer@0: protected VVector() {} samer@0: samer@0: public VVector(Node node, Vec v) { samer@0: super(node); vec=v; setAgent(this); samer@0: Shell.registerViewable(this); samer@0: } samer@0: samer@0: public VVector(Node node, double [] x) { this(node,new Vec.ForArray(x)); } samer@0: public VVector(String nm, double [] x) { this(new Node(nm), x); } samer@0: public VVector(String nm, int n) { this(new Node(nm), n); } samer@0: public VVector(Node node, int n) { samer@0: this(node,new Vec.ForArray(new double[n])); samer@0: } samer@0: samer@0: public void addSaver() { addAgent(new Saver(this,getNode())); } samer@0: samer@0: // Vec implementation samer@0: public Iterator iterator() { return vec.iterator(); } samer@0: public int size() { return vec.size(); } samer@0: public Mat mat() { return vec.mat(); } samer@0: public double[] array() { return vec.array(); } samer@0: samer@0: public Vec getVec() { return vec; } samer@0: public Viewer getViewer() samer@0: { samer@0: BaseViewer vwr = new BaseViewer(this); samer@0: StringBuffer buf=new StringBuffer(); samer@0: samer@0: buf.append(getLabel()) samer@0: .append(" (").append(vec.size()) samer@0: .append(")"); samer@0: vwr.setText(buf.toString()); samer@0: samer@0: return vwr; samer@0: } samer@0: samer@0: public void copyFrom(double[] y) { Mathx.copy(y,array()); changed(); } samer@0: public void copyTo(double[] y) { Mathx.copy(array(),y); } samer@0: // Saveable implementation samer@0: public void save(OutputStream out) throws Exception { samer@0: new ObjectOutputStream(out).writeObject(array()); samer@0: } samer@0: samer@0: public void load(InputStream in) throws Exception { samer@0: Object o=new ObjectInputStream(in).readObject(); samer@0: Mathx.copy((double [])o,array()); changed(); samer@0: } samer@0: samer@0: /** Write the given Vec to a PrintWriter as one line of text, samer@0: consisting of space delimited numbers. */ samer@0: samer@0: public void write(Writer w) { print(new PrintWriter(w)); } samer@0: public void print(PrintWriter prn) { samer@0: Vec.Iterator i=vec.iterator(); samer@0: prn.print(i.next()); samer@0: while (i.more()) { samer@0: prn.print(' '); samer@0: prn.print(i.next()); samer@0: } samer@0: prn.println(); samer@0: prn.flush(); samer@0: } samer@0: samer@0: /** Reads a line of numbers from the reader and stores in the Vec */ samer@0: public void read(Reader input) throws IOException samer@0: { samer@0: StreamTokenizer tok= new StreamTokenizer(new BufferedReader(input)); samer@0: samer@0: /* samer@0: a) words are made from only +,-,.,e,E, or digits samer@0: b) if other tokens may exist in a line, these are ignored samer@0: c) if there is too much stuff on one line, the rest is discarded. samer@0: d) if there aren't enough numbers, throw an exception. samer@0: */ samer@0: samer@0: tok.resetSyntax(); samer@0: tok.wordChars('+','+'); samer@0: tok.wordChars('-','-'); samer@0: tok.wordChars('0','9'); samer@0: tok.wordChars('.','.'); samer@0: tok.wordChars('e','e'); samer@0: tok.wordChars('E','E'); samer@0: tok.commentChar('#'); samer@0: tok.commentChar(';'); samer@0: tok.commentChar('%'); samer@0: tok.whitespaceChars(0, ' '); samer@0: tok.eolIsSignificant(true); samer@0: samer@0: // Ignore initial empty lines samer@0: while (tok.nextToken() == StreamTokenizer.TT_EOL); samer@0: if (tok.ttype == StreamTokenizer.TT_EOF) samer@0: throw new EOFException("EOF on vector read."); samer@0: samer@0: double [] x=vec.array(); samer@0: int i=0; samer@0: samer@0: // get first x.length words and convert to numbers samer@0: do { samer@0: if (tok.ttype==StreamTokenizer.TT_WORD) samer@0: x[i++]=Double.parseDouble(tok.sval); samer@0: } while (tok.nextToken()!=StreamTokenizer.TT_EOL && i1) return new ArrayImageSource(array,w,h); samer@0: else return new ArrayVImageSource(array); samer@0: } else { samer@0: return new IteratorImageSource(getVec(),w,h); samer@0: } samer@0: } samer@0: samer@0: private ImageViewer createVectorImage( final Node n, int w, int h) samer@0: { samer@0: samer@0: /* samer@0: The VImageViewer handles displaying the image of samer@0: a supplied ImageSource, but this object handles samer@0: scaling of the colour map to match the range of samer@0: values in a Vec, accessed by iterator rather than samer@0: array. samer@0: */ samer@0: return new ImageViewer( createImageSource(w,h), this) { samer@0: public void scale() samer@0: { samer@0: Vec.Iterator i=vec.iterator(); samer@0: double max, min, x; samer@0: samer@0: min=max=i.next(); samer@0: while (i.more()) { samer@0: x=i.next(); samer@0: if (x>max) max=x; samer@0: if (x