Esempio n. 1
0
//Swap rows in a col major array
void swapRows(int rows, int cols, double * array, int rowA, int rowB)
{
	double * tempRow  = Calloc(cols, double);

	copyVect(cols, array+rowA, rows, tempRow, 1);
	copyVect(cols, array+rowB, rows, array+rowA, rows);
	copyVect(cols, tempRow, 1, array+rowB, rows);
	Free(tempRow);
}
Esempio n. 2
0
/*
Algorithm taken from Matrix Algorithms Vol. II by G.W. Stewart.
His original pseudocode is in the comments.

This function takes a vector a and produces a u that generates the
Householder transformation H = I - uuH such that Ha = ve1.

n is the length of the vectors.
*/
void housegen(Complex *a, Complex *u, Complex *v, int n)
{
	int i;
	Real tmp;
	Complex rho;
	
	//u = a
	copyVect(a,u,n);
	
	//v = ||a||2
	v->real = norm(a,n);
	v->imag = 0.0;//must be done after norm is taken above!
	
	//if(v = 0)u[1] = sqrt(2); return; fi  <-no clue what 'fi' is
	if(v->real == 0.0)//v can only be real right now   should i be using epsilon?
	{
		u[0].real = sqrt(2);
		u[0].imag = 0;
		return;
	}
	
	//if(u[1] != 0)
	if(u[0].real != 0.0 || u[0].imag != 0.0)// not sure if I should use an epsilon here?
	{
		//rho = u_bar[1]/|u[1]|
		tmp = ABS(u[0]);
		rho.real = u[0].real/tmp;
		rho.imag = -u[0].imag/tmp;
	}
	else//else rho = 1;
	{
		rho.real = 1.0;
		rho.imag = 0.0;
	}
		
	//u = (rho/v)*u
	for(i = 0; i < n; i++)
	{
		//v can still only be real at this point
		u[i] = complexMult(rho, u[i]);
		u[i].real /= v->real;
		u[i].imag /= v->real;
	}
		
	//u[1] = 1 + u[1]
	u[0].real = 1.0 + u[0].real;
	
	
	//u = u/sqrt(u[1])
	tmp = u[0].real;
	for(i = 0; i < n; i++)
	{
		u[i].real = u[i].real/sqrt(tmp);//I think u[0] has tpo be real here
		u[i].imag = u[i].imag/sqrt(tmp);
	}
	
	//v = -rho_bar*v
	rho.real = -rho.real;
	*v = complexMult(rho, *v);
}
Esempio n. 3
0
void copyMat(Complex *src, Complex *dest, int dim1, int dim2)
{
	copyVect(src, dest, dim1*dim2);
}
Esempio n. 4
0
/*
Algorithm taken from Matrix Algorithms Vol. II by G.W. Stewart.

This function takes a vector A of order n  and reduces it to Hessenberg form
by Householder transformations.

In the future it may be possible to remove H entirely and do the transformation
in place.

A is an n*n matrix that I am transforming
H is an n*n matrix where I will put the result
Q is an n*n matrix where I will accumulate the transformations
u is a vector of length n for scratch work.
vH is another vector of length n for scratch work
*/
void hessreduce(Complex *A, Complex *H, Complex *Q, Complex *u, Complex *vH, int n)
{
	int k, i, j, l;
	Complex tmp;
	
	if(n < 2)
		return;
	
	//Reduce A
	//H = A
	copyMat(A,H,n,n);
	
	//3. for k = 1 to n-2
	for(k = 0; k < n-2; k++)
	{
		//Generate the Transformation
		//housegen(H[k+1:n,k],u,H[k+1,k])
		housegen(&INDEX(H,n,(k+1),k),u+k+1,&INDEX(H,n,(k+1),k),n-k-1);
		
		//5. Q[k+1:n,k] = u
		copyVect(u+k+1, &INDEX(Q, n, (k+1), k), n-k-1);
		
		//Premultiply the transformation
		//6. vH = uH*H[k+1:n,k+1:n]
		for(i = k+1; i < n; i++)
		{
			vH[i].real = 0.0;
			vH[i].imag = 0.0;
			
			for(j = k+1; j < n; j++)
			{
				tmp = INDEX(H,n,j,i);
				vH[i].real += u[j].real * tmp.real;
				vH[i].real += u[j].imag * tmp.imag;//minus minus for hermitian
				vH[i].imag += u[j].real * tmp.imag;
				vH[i].imag -= u[j].imag * tmp.real;//minus sign is for hermitian
			}
		}
		
		//7. H[k+1:n,k+1:n] = H[k+1:n, k+1:n] - u*vH
		for(i = k+1; i < n; i++)
		{
			for(j = k+1; j < n; j++)
			{
				INDEX(H,n,i,j).real -= u[i].real *vH[j].real;
				INDEX(H,n,i,j).real += u[i].imag *vH[j].imag;
				INDEX(H,n,i,j).imag -= u[i].real *vH[j].imag;
				INDEX(H,n,i,j).imag -= u[i].imag *vH[j].real;
			}
		}
						
		//H[k+2:n,k] = 0
		for(i = k+2; i < n; i++)
		{
			INDEX(H,n,i,k).real = 0.0;
			INDEX(H,n,i,k).imag = 0.0;
		}
		
		//Postmultiply the transformation
		//9. v = H[1:n, k+1:n]*u
		//I will use the variable vH for v (for space).
		for(i = 0; i < n; i++)
		{
			vH[i].real = 0.0;
			vH[i].imag = 0.0;
			for(j = k+1; j < n; j++)
			{
				tmp = INDEX(H,n,i,j);
				vH[i].real += tmp.real * u[j].real;
				vH[i].real -= tmp.imag * u[j].imag;
				vH[i].imag += tmp.real * u[j].imag;
				vH[i].imag += tmp.imag * u[j].real;
			}
		}
		
		//10. H[1:n, k+1:n] = H[1:n,k+1:n] - v*uH
		for(i = 0; i < n; i++)
		{
			for(j = k+1; j < n; j++)
			{
				INDEX(H,n,i,j).real -= vH[i].real * u[j].real;
				INDEX(H,n,i,j).real -= vH[i].imag * u[j].imag;
				INDEX(H,n,i,j).imag += vH[i].real * u[j].imag;
				INDEX(H,n,i,j).imag -= vH[i].imag * u[j].real;
			}
		}
	}//end k
	
	//Accumulate the Transformations
	//12. Q[:,n] = e_n; Q[:,n-1] = e_(n-1)
	for(i = 0; i < n; i++)
	{
		INDEX(Q,n,i,(n-1)).real = 0.0;
		INDEX(Q,n,i,(n-1)).imag = 0.0;
		INDEX(Q,n,i,(n-2)).real = 0.0;
		INDEX(Q,n,i,(n-2)).imag = 0.0;
	}
	INDEX(Q,n,(n-1),(n-1)).real = 1.0;
	INDEX(Q,n,(n-2),(n-2)).real = 1.0;
	
	//13. for k = n-2 to 1 by -1
	for(k = n-3; k >= 0; k--)
	{	
		//14. u = Q[k+1:n,k]
		copyVect(&INDEX(Q,n,(k+1),k), u+k+1, n-(k+1));
		
		//15. vH = uH*Q[k+1:n,k+1:n]//Q[k+1:n,k] = u
		for(i = k+1; i < n; i++)
		{
			vH[i].real = 0.0;
			vH[i].imag = 0.0;
			for(j = k+1; j < n; j++)
			{
				tmp.real = u[j].real;
				tmp.imag = -u[j].imag;
				tmp = complexMult(tmp, INDEX(Q, n, j, i));
				vH[i].real += tmp.real;
				vH[i].imag += tmp.imag;
			}
		}
		
		//16. Q[k+1:n, k+1:n] = Q[k+1:n, k+1:n] -u*vH
		for(i = k+1; i < n; i++)
		{
			for(j = k+1; j < n; j++)
			{
				tmp = complexMult(u[i],vH[j]);
				INDEX(Q,n,i,j).real -= tmp.real;
				INDEX(Q,n,i,j).imag -= tmp.imag;	
			}
		}
		
		//17. Q[:,k] = e_k
		for(i = 0; i < n; i++)
		{
			INDEX(Q,n,i,k).real = 0.0;
			INDEX(Q,n,i,k).imag = 0.0;
		}
		INDEX(Q,n,k,k).real = 1.0;
		
	}// 18. end for k
}//end hessreduce