view src/samer/maths/RowColumn.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	RowColumn.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.types.*;
import  samer.core.util.*;
import  java.util.*;

/**
	Looks like a vector externally, but reads data
	from a row or column of a matrix. Provides 
	commands for setting which row or column to use,
	and for switching between rows and columns.
  */

public class RowColumn extends VVector implements Mat, Observer
{
	Matrix			M;
	VInteger			num; 
	int				rowcol;
	Mat				mat;

	public final static Object FLIPPED   = new Object();
	public final static Object SWITCHED  = new Object();

	public RowColumn(Matrix A) { this( new Node("rowcolumn",A.getNode()), A); }
	public RowColumn(Node n, Matrix A) 
	{ 
		super(n,A.getColumn(0));

		Shell.push(node);
		M=A; rowcol=COL;
		boolean rowwise=Shell.getBoolean("rowwise",(A.getRowDimension()==1));
		if (rowwise) { vec=A.getRow(0); rowcol=ROW; }
		Shell.pop();

		if (rowcol==ROW) createVRow();
		else createVColumn();

		M.addObserver(this);
	}

	// Vec implementation
	public double[] array() { return null; }
	public Vec getVec() { return this; }
	public Mat mat() { if (mat==null) mat=vec.mat(); return this; }

	// Mat implementation
	public int width() { return mat.width(); }
	public int height() { return mat.height(); }
	public double get( int i, int j) { return mat.get(i,j); }
	public void set( int i, int j, double t) { mat.set(i,j,t); }

	private void createVRow()
	{
		Shell.push(getNode().getParent());
		num = new VInteger("row",0,Variable.NOINIT);
		num.setRange(0,M.getRowDimension()-1);
		num.addObserver(this);
		Shell.registerViewable(num);
		Shell.pop();
	}

	private void createVColumn()
	{
		Shell.push(getNode().getParent());
		num = new VInteger("column",0,Variable.NOINIT);
		num.setRange(0,M.getColumnDimension()-1);
		num.addObserver(this);
		Shell.registerViewable(num);
		Shell.pop();
	}

	public void dispose() 
	{
		Shell.deregisterViewable(num);
		M.deleteObserver(this);
		num.dispose();
		super.dispose();
	}

	public void setNum(int n) { num.value=n; num.changed(); }

	public void setRow(int r) { 
		num.value=r; vec=M.getRow(r);
		if (mat!=null) mat=vec.mat();
		if (rowcol==ROW) changed(SWITCHED);
		else { rowcol=ROW; changed(FLIPPED); }
	}

	public void setColumn(int r) { 
		num.value=r; vec=M.getColumn(r); 
		if (mat!=null) mat=vec.mat();
		if (rowcol==COL) changed(SWITCHED);
		else { rowcol=COL; changed(FLIPPED); }
	}

	public void getCommands(Agent.Registry r) {
		super.getCommands(r); r.group();
		r.add("row").add("column").add("dispose");
	}

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

			if (rowcol==COL) {
				num.deleteObserver(this);
				num.dispose();
				createVRow();
				setRow(0);
			}

			// no need to get number: num is automatically exposed
			// env.datum().get(num);

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

			if (rowcol==ROW) {
				num.deleteObserver(this);
				num.dispose();
				createVColumn();
				setColumn(0);
			}

			// no need to get number: num is automatically exposed
			// env.datum().get(num);
		} else if (cmd.equals("dispose")) {
			dispose();
		} else super.execute(cmd,env);
	}

	public void notifyObservers(Object s) {
		super.notifyObservers(s);
		if (s!=Viewable.DISPOSING && s!=RowColumn.SWITCHED) {
			M.changed(this); // pass notification onto matrix observers
		}
	}

	public void update(Observable o, Object s) { // &&&
		if (M.equals(o)) { // Matrix changed
			if (s==Viewable.DISPOSING)	dispose();
			else if (s!=this)	super.notifyObservers(this);
		} else if (num.equals(o)) {
			if (rowcol==ROW) setRow(num.value);
			else setColumn(num.value);
		}
	}

	private final static int ROW = 1;
	private final static int COL = 2;
}