annotate src/samer/maths/VVector.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
rev   line source
samer@0 1 /*
samer@0 2 * VVector.java
samer@0 3 *
samer@0 4 * Copyright (c) 2000, Samer Abdallah, King's College London.
samer@0 5 * All rights reserved.
samer@0 6 *
samer@0 7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0 8 * without even the implied warranty of MERCHANTABILITY or
samer@0 9 * FITNESS FOR A PARTICULAR PURPOSE.
samer@0 10 */
samer@0 11
samer@0 12 package samer.maths;
samer@0 13 import samer.core.*;
samer@0 14 import samer.core.util.*;
samer@0 15 import samer.tools.*;
samer@0 16 import java.awt.*;
samer@0 17 import java.awt.event.*;
samer@0 18 import java.util.*;
samer@0 19 import java.io.*;
samer@0 20 /**
samer@0 21 A Viewable Vec. The default viewer displays only
samer@0 22 the name and size of the vector, but the attached
samer@0 23 Agent allows creation of other types of viewer.
samer@0 24 */
samer@0 25
samer@0 26 public class VVector extends Viewable implements Vec, Agent, Saveable
samer@0 27 {
samer@0 28 Vec vec;
samer@0 29
samer@0 30 protected VVector() {}
samer@0 31
samer@0 32 public VVector(Node node, Vec v) {
samer@0 33 super(node); vec=v; setAgent(this);
samer@0 34 Shell.registerViewable(this);
samer@0 35 }
samer@0 36
samer@0 37 public VVector(Node node, double [] x) { this(node,new Vec.ForArray(x)); }
samer@0 38 public VVector(String nm, double [] x) { this(new Node(nm), x); }
samer@0 39 public VVector(String nm, int n) { this(new Node(nm), n); }
samer@0 40 public VVector(Node node, int n) {
samer@0 41 this(node,new Vec.ForArray(new double[n]));
samer@0 42 }
samer@0 43
samer@0 44 public void addSaver() { addAgent(new Saver(this,getNode())); }
samer@0 45
samer@0 46 // Vec implementation
samer@0 47 public Iterator iterator() { return vec.iterator(); }
samer@0 48 public int size() { return vec.size(); }
samer@0 49 public Mat mat() { return vec.mat(); }
samer@0 50 public double[] array() { return vec.array(); }
samer@0 51
samer@0 52 public Vec getVec() { return vec; }
samer@0 53 public Viewer getViewer()
samer@0 54 {
samer@0 55 BaseViewer vwr = new BaseViewer(this);
samer@0 56 StringBuffer buf=new StringBuffer();
samer@0 57
samer@0 58 buf.append(getLabel())
samer@0 59 .append(" (").append(vec.size())
samer@0 60 .append(")");
samer@0 61 vwr.setText(buf.toString());
samer@0 62
samer@0 63 return vwr;
samer@0 64 }
samer@0 65
samer@0 66 public void copyFrom(double[] y) { Mathx.copy(y,array()); changed(); }
samer@0 67 public void copyTo(double[] y) { Mathx.copy(array(),y); }
samer@0 68 // Saveable implementation
samer@0 69 public void save(OutputStream out) throws Exception {
samer@0 70 new ObjectOutputStream(out).writeObject(array());
samer@0 71 }
samer@0 72
samer@0 73 public void load(InputStream in) throws Exception {
samer@0 74 Object o=new ObjectInputStream(in).readObject();
samer@0 75 Mathx.copy((double [])o,array()); changed();
samer@0 76 }
samer@0 77
samer@0 78 /** Write the given Vec to a PrintWriter as one line of text,
samer@0 79 consisting of space delimited numbers. */
samer@0 80
samer@0 81 public void write(Writer w) { print(new PrintWriter(w)); }
samer@0 82 public void print(PrintWriter prn) {
samer@0 83 Vec.Iterator i=vec.iterator();
samer@0 84 prn.print(i.next());
samer@0 85 while (i.more()) {
samer@0 86 prn.print(' ');
samer@0 87 prn.print(i.next());
samer@0 88 }
samer@0 89 prn.println();
samer@0 90 prn.flush();
samer@0 91 }
samer@0 92
samer@0 93 /** Reads a line of numbers from the reader and stores in the Vec */
samer@0 94 public void read(Reader input) throws IOException
samer@0 95 {
samer@0 96 StreamTokenizer tok= new StreamTokenizer(new BufferedReader(input));
samer@0 97
samer@0 98 /*
samer@0 99 a) words are made from only +,-,.,e,E, or digits
samer@0 100 b) if other tokens may exist in a line, these are ignored
samer@0 101 c) if there is too much stuff on one line, the rest is discarded.
samer@0 102 d) if there aren't enough numbers, throw an exception.
samer@0 103 */
samer@0 104
samer@0 105 tok.resetSyntax();
samer@0 106 tok.wordChars('+','+');
samer@0 107 tok.wordChars('-','-');
samer@0 108 tok.wordChars('0','9');
samer@0 109 tok.wordChars('.','.');
samer@0 110 tok.wordChars('e','e');
samer@0 111 tok.wordChars('E','E');
samer@0 112 tok.commentChar('#');
samer@0 113 tok.commentChar(';');
samer@0 114 tok.commentChar('%');
samer@0 115 tok.whitespaceChars(0, ' ');
samer@0 116 tok.eolIsSignificant(true);
samer@0 117
samer@0 118 // Ignore initial empty lines
samer@0 119 while (tok.nextToken() == StreamTokenizer.TT_EOL);
samer@0 120 if (tok.ttype == StreamTokenizer.TT_EOF)
samer@0 121 throw new EOFException("EOF on vector read.");
samer@0 122
samer@0 123 double [] x=vec.array();
samer@0 124 int i=0;
samer@0 125
samer@0 126 // get first x.length words and convert to numbers
samer@0 127 do {
samer@0 128 if (tok.ttype==StreamTokenizer.TT_WORD)
samer@0 129 x[i++]=Double.parseDouble(tok.sval);
samer@0 130 } while (tok.nextToken()!=StreamTokenizer.TT_EOL && i<x.length);
samer@0 131 // !! what if EOF?
samer@0 132 if (i<(x.length-1)) throw new IOException("not enough numbers");
samer@0 133
samer@0 134 // now mop up rest of line
samer@0 135 while (tok.ttype!=StreamTokenizer.TT_EOL) tok.nextToken();
samer@0 136 changed();
samer@0 137 }
samer@0 138
samer@0 139 public void getCommands(Registry r) {
samer@0 140 r.add("zeros").add("negate").add("set").group();
samer@0 141 r.add("plotter")
samer@0 142 .add("image")
samer@0 143 .add("reshaped image")
samer@0 144 .add("trace")
samer@0 145 .add("image editor")
samer@0 146 .add("plotter editor")
samer@0 147 .add("multitrace");
samer@0 148 r.group();
samer@0 149 r.add("publish");
samer@0 150
samer@0 151 }
samer@0 152
samer@0 153 private void expose(Viewer v) { Shell.expose(v,"window"); }
samer@0 154
samer@0 155 public void execute(String cmd, Environment env) throws Exception
samer@0 156 {
samer@0 157 if (cmd.equals("zeros")) {
samer@0 158
samer@0 159 double [] x = vec.array();
samer@0 160 if (x!=null) Mathx.zero(x);
samer@0 161 else { // try using Mat interface instead
samer@0 162 Mat mat = vec.mat();
samer@0 163 if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,0);
samer@0 164 else throw new Exception("Vector inaccessible: "+getLabel());
samer@0 165 }
samer@0 166 changed();
samer@0 167
samer@0 168 } else if (cmd.equals("set")) {
samer@0 169
samer@0 170 double y=X._double(env.datum(),1);
samer@0 171 double [] x = vec.array();
samer@0 172 if (x!=null) Mathx.setAll(x,y);
samer@0 173 else { // try using Mat interface instead
samer@0 174 Mat mat = vec.mat();
samer@0 175 if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,y);
samer@0 176 else throw new Exception("Vector inaccessible: "+getLabel());
samer@0 177 }
samer@0 178 changed();
samer@0 179
samer@0 180 } else if (cmd.equals("negate")) {
samer@0 181
samer@0 182 double [] x = vec.array();
samer@0 183 if (x!=null) Mathx.negate(x);
samer@0 184 else { // try using Mat interface instead
samer@0 185 Mat mat = vec.mat();
samer@0 186 if (mat!=null) for (int i=0; i<mat.width(); i++) mat.set(1,i,-mat.get(1,i));
samer@0 187 else throw new Exception("Vector inaccessible: "+getLabel());
samer@0 188 }
samer@0 189 changed();
samer@0 190
samer@0 191 } else if (cmd.equals("plotter")) {
samer@0 192
samer@0 193 pushNode("plotter");
samer@0 194 expose(new VectorPlotter(this,getVec()));
samer@0 195 Shell.pop();
samer@0 196
samer@0 197 } else if (cmd.equals("plotter editor")) {
samer@0 198
samer@0 199 pushNode("editor.plotter");
samer@0 200 expose(new VectorEditor(this,getVec()));
samer@0 201 Shell.pop();
samer@0 202
samer@0 203 } else if (cmd.equals("image")) {
samer@0 204
samer@0 205 Node n=pushNode("image");
samer@0 206 expose(createVectorImage(n,vec.size(),1));
samer@0 207 Shell.pop();
samer@0 208
samer@0 209 } else if (cmd.equals("reshaped image")) {
samer@0 210
samer@0 211 Node n=pushNode("reshaped.image");
samer@0 212 int w=Shell.getInt("width",1);
samer@0 213 int h=Shell.getInt("height",vec.size());
samer@0 214 expose(createVectorImage( n, w, h));
samer@0 215 Shell.pop();
samer@0 216
samer@0 217 } else if (cmd.equals("image editor")) {
samer@0 218
samer@0 219 Node n=pushNode("editor.image");
samer@0 220
samer@0 221 final Shell.Window win = Shell.getWindow("window");
samer@0 222 final ImageViewer vwr = createVectorImage(n,vec.size(),1);
samer@0 223 final MatEditor editor = new MatEditor(mat(),vwr,this,vwr);
samer@0 224
samer@0 225 win.container().setLayout( new BorderLayout(6,6));
samer@0 226 win.container().add( vwr.getComponent(), "Center");
samer@0 227 // win.container().add( editor.setto.getViewer().getComponent(),"South");
samer@0 228 Shell.registerViewable(editor.setto);
samer@0 229 win.addWindowListener( new WindowAdapter() {
samer@0 230 public void windowClosing(WindowEvent e) {
samer@0 231 editor.detach();
samer@0 232 vwr.detach();
samer@0 233 win.dispose();
samer@0 234 }
samer@0 235 } );
samer@0 236 win.expose();
samer@0 237
samer@0 238 // vwr.exposeCommands(this);
samer@0 239
samer@0 240 Shell.pop();
samer@0 241
samer@0 242 } else if (cmd.equals("trace")) {
samer@0 243
samer@0 244 Node node=pushNode("trace");
samer@0 245 ImageSourceBase imgsrc=createImageSource(1,vec.size());
samer@0 246 expose(new ImageTrace(imgsrc,this));
samer@0 247 Shell.pop();
samer@0 248
samer@0 249 } else if (cmd.equals("multitrace")) {
samer@0 250
samer@0 251 Node node=pushNode("trace");
samer@0 252 expose(new VectorTraceObs(this,node));
samer@0 253 Shell.pop();
samer@0 254 } else if (cmd.equals("publish")) {
samer@0 255 Shell.put(X.string(env.datum(),node.fullName()),this);
samer@0 256 }
samer@0 257 }
samer@0 258
samer@0 259
samer@0 260 private Node pushNode(String nm) {
samer@0 261 Node n=new Node(nm,getNode());
samer@0 262 Shell.push(n);
samer@0 263 return n;
samer@0 264 }
samer@0 265
samer@0 266 private ImageSourceBase createImageSource(int w, int h)
samer@0 267 {
samer@0 268 // this chooses an ImageSource depending on
samer@0 269 // the capabilities of the Vec
samer@0 270 double [] array=array();
samer@0 271
samer@0 272 if (array!=null) {
samer@0 273 if (w>1) return new ArrayImageSource(array,w,h);
samer@0 274 else return new ArrayVImageSource(array);
samer@0 275 } else {
samer@0 276 return new IteratorImageSource(getVec(),w,h);
samer@0 277 }
samer@0 278 }
samer@0 279
samer@0 280 private ImageViewer createVectorImage( final Node n, int w, int h)
samer@0 281 {
samer@0 282
samer@0 283 /*
samer@0 284 The VImageViewer handles displaying the image of
samer@0 285 a supplied ImageSource, but this object handles
samer@0 286 scaling of the colour map to match the range of
samer@0 287 values in a Vec, accessed by iterator rather than
samer@0 288 array.
samer@0 289 */
samer@0 290 return new ImageViewer( createImageSource(w,h), this) {
samer@0 291 public void scale()
samer@0 292 {
samer@0 293 Vec.Iterator i=vec.iterator();
samer@0 294 double max, min, x;
samer@0 295
samer@0 296 min=max=i.next();
samer@0 297 while (i.more()) {
samer@0 298 x=i.next();
samer@0 299 if (x>max) max=x;
samer@0 300 if (x<min) min=x;
samer@0 301 }
samer@0 302
samer@0 303 getVMap().setDomain(min,max);
samer@0 304 getVMap().changed(this);
samer@0 305 }
samer@0 306 };
samer@0 307 }
samer@0 308 }
samer@0 309
samer@0 310
samer@0 311 class VectorTraceObs extends VectorTrace implements Observer {
samer@0 312 Observable obs;
samer@0 313 Node node;
samer@0 314
samer@0 315 VectorTraceObs(VVector v, Node n) {
samer@0 316 super(v);
samer@0 317 obs=v;
samer@0 318 node=n;
samer@0 319 }
samer@0 320
samer@0 321 public void attach() { super.attach(); obs.addObserver(this); }
samer@0 322 public void detach() { obs.deleteObserver(this); super.detach(); }
samer@0 323 public void update(Observable o, Object arg)
samer@0 324 {
samer@0 325 if (o==obs) {
samer@0 326 if (arg==Viewable.DISPOSING) {
samer@0 327 Shell.releaseViewer(this);
samer@0 328 } else {
samer@0 329 try { run(); }
samer@0 330 catch (Exception ex) {}
samer@0 331 }
samer@0 332 } else super.update(o,arg);
samer@0 333 }
samer@0 334 }