#include "gpklib/assert.h"
#include "m22v2.h"


vector2 operator*(C matrix22& a, C vector2& b)
{
 C vector_space *out = vector_space::vseQ(a.in, b.space())
							? a.out : &vector_space::bad;

 return vector2(a(0,0)*b(0)+a(0,1)*b(1), a(1,0)*b(0)+a(1,1)*b(1), out);
}



vector2 operator*(C vector2& b, C matrix22& a)
{
 C vector_space *in = vector_space::vseQ(a.out, b.space())
							? a.in : &vector_space::bad;

 return vector2(b(0)*a(0,0)+b(1)*a(1,0), b(0)*a(0,1)+b(1)*a(1,1), in);
}



matrix22 outer(C vector2& a, C vector2& b)
{
 return matrix22(a(0)*b(0), a(0)*b(1), a(1)*b(0), a(1)*b(1),
						b.space(), a.space());
}


vector2 row(C matrix22& a, int row_idx)
{
 return vector2(a(row_idx, 0), a(row_idx, 1), a.out);
}


vector2 column(C matrix22& a, int col_idx)
{
 return vector2(a(0, col_idx), a(1, col_idx), a.in);
}


double quadratic_form(C vector2& a, C matrix22& b)
{
	assert(vector_space::vseQ(a.space(), b.in));
	assert(vector_space::vseQ(a.space(), b.out));

	return a(0)*a(0)*b(0,0)
		+ a(0)*a(1)*b(0,1)
		+ a(1)*a(0)*b(1,0)
		+ a(1)*a(1)*b(1,1);
}
