class Matrix
{
	//float array[][];
	// This is one example of why sane people hate Java!
	// a two dimensional array is not "flat", meaning I can't "clone()" it using a 
	// bitwise copy.
	float array[];
	int rows;
	int cols;

	public Matrix(int numrows, int numcols)
	{
		rows = numrows;
		cols = numcols;
		array = new float[cols*rows];
	}
	public Matrix(Matrix copy)
	{
		rows = copy.rows;
		cols = copy.cols;
		array = (float[])copy.array.clone();
	}
	public Matrix add( Matrix right) throws SizeException
	{
		if (cols != right.cols || rows != right.rows)
		{
			throw new SizeException();
		}

		else
		{
			Matrix result = new Matrix(this);
			float elem = 0;
			for ( int i = 0; i < rows ; i++)
			{
				for (int j = 0; j < cols ; j++)
				{
					result.array[j*rows+i] += right.array[j*rows+i];
				}
			}
			return result;
		}
	}
	public void addto( Matrix right) throws SizeException
	{
		if (cols != right.cols || rows != right.rows)
		{
			throw new SizeException();
		}

		else
		{
			for ( int i = 0; i < rows ; i++)
			{
				for (int j = 0; j < cols ; j++)
				{
					array[j*rows+i] += right.array[j*rows+i];
				}
			}
		}
	}
	public void copy(Matrix other)
	{
		rows = other.rows;
		cols = other.cols;
		array = (float[])other.array.clone();
	}
	public float get(int i, int j)
	{
		return array[(j-1)*rows+i-1];
	}
	public Matrix multiply( Matrix right) throws SizeException
	{
		if (cols != right.rows)
		{
			throw new SizeException();
		}

		else
		{
			Matrix result = new Matrix(rows, right.cols);
			float elem = 0;
			for ( int i = 0; i < rows ; i++)
			{
				for (int j = 0; j < right.cols ; j++)
				{
					elem = 0;
					for ( int n = 0; n < cols; n++)
					{
						elem += array[n*rows+i] *
							right.array[j*right.rows+n];
					}
					result.array[j*rows+i] = elem;
				}
			}
			return result;
		}
	}
	public void multiplyScalar( float scale) 
	{
		for ( int i = 0; i < rows ; i++)
		{
			for (int j = 0; j < cols ; j++)
			{
				array[j*rows+i] *= scale;
			}
		}
	}
	public void multiplyTo( Matrix right) throws SizeException
	{
		if (cols != right.rows && rows != right.cols)
		{
			throw new SizeException();
		}

		else
		{
			Matrix result = new Matrix(rows, right.cols);
			float elem = 0;
			for ( int i = 0; i < rows ; i++)
			{
				for (int j = 0; j < right.cols ; j++)
				{
					elem = 0;
					for ( int n = 0; n < cols; n++)
					{
						elem += array[n*rows+i] *
							right.array[j*right.rows+n];
					}
					result.array[j*rows+i] = elem;
				}
			}
			array = result.array;
		}
	}
	public void set(int i, int j, float value)
	{
		array[(j-1)*rows+i-1] = value;
	}
}