int test_over_gelsd(StreamType& oss)
{
	typedef typename bindings::value_type<MatType>::type val_t;
	typedef typename bindings::remove_imaginary<val_t>::type real_t;
	const real_t rcond = -1;    // use machine precision
	fortran_int_t rank;

	// return value
	int err = 0;

	// overdetermined matrix test
	MatType mat(MatrixGenerator<MatType>()(row_size, col_range));
	VecType vec(VectorGenerator<VecType>()(row_size));

	//const int m = bindings::size_row(mat);
	const int n = bindings::size_column(mat);
	bindings::detail::array<real_t> s(n);

#if USE_OPTIMAL_WORKSPACE
	MatType optimalmat(mat);
	VecType optimalvec(vec);
	err += lapack::gelsd(optimalmat, optimalvec, s, rcond, rank, lapack::optimal_workspace());
	VecType optimalanswer(ublas::project(optimalvec, ublas::range(0, n)));
	VecType optimal_check = ublas::prod(mat, optimalanswer);
#endif
#if USE_MINIMAL_WORKSPACE
	MatType minimalmat(mat);
	VecType minimalvec(vec);
	err += lapack::gelsd(minimalmat, minimalvec, s, rcond, rank, lapack::minimal_workspace());
	VecType minimalanswer(ublas::project(minimalvec, ublas::range(0, n)));
	VecType minimal_check = ublas::prod(mat, minimalanswer);
#endif

	matrix_print(oss, "A", mat);
	oss << std::endl;
	vector_print(oss, "B", vec);
	oss << std::endl;

#if USE_OPTIMAL_WORKSPACE
	vector_print(oss, "optimal workspace x", optimalanswer);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	vector_print(oss, "minimal workspace x", minimalanswer);
	oss << std::endl;
#endif
#if USE_OPTIMAL_WORKSPACE
	// check A*x=B
	vector_print(oss, "optimal A*x=B", optimal_check);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	vector_print(oss, "minimal A*x=B", minimal_check);
	oss << std::endl;
#endif

	return err;
}
int test_multiple_gelsd(StreamType& oss)
{
	// return value
	int err = 0;

	// multiple solutions vectors test
	MatType mat(MatrixGenerator<MatType>()(row_size, col_size));
	MatType vec(mat.size1(), 2);
	ublas::column(vec, 0) = VectorGenerator<VecType>()(mat.size1());
	ublas::column(vec, 1) = VectorGenerator<VecType>()(mat.size1());

	const int m = traits::matrix_size1(mat);
	const int n = traits::matrix_size2(mat);
	const int nrhs = traits::matrix_size2(vec);

#if USE_OPTIMAL_WORKSPACE
	MatType optimalmat(mat);
	MatType optimalvec(vec);
	err += lapack::gelsd(optimalmat, optimalvec, lapack::optimal_workspace());
	MatType optimalanswer(ublas::project(optimalvec, ublas::range(0, n), ublas::range(0, nrhs)));
	MatType optimal_check = ublas::prod(mat, optimalanswer);
#endif
#if USE_MINIMAL_WORKSPACE
	MatType minimalmat(mat);
	MatType minimalvec(vec);
	err += lapack::gelsd(minimalmat, minimalvec, lapack::minimal_workspace());
	MatType minimalanswer(ublas::project(minimalvec, ublas::range(0, n), ublas::range(0, nrhs)));
	MatType minimal_check = ublas::prod(mat, minimalanswer);
#endif

	matrix_print(oss, "A", mat);
	oss << std::endl;
	matrix_print(oss, "B", vec);
	oss << std::endl;

#if USE_OPTIMAL_WORKSPACE
	matrix_print(oss, "optimal workspace x", optimalanswer);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	matrix_print(oss, "minimal workspace x", minimalanswer);
	oss << std::endl;
#endif
#if USE_OPTIMAL_WORKSPACE
	// check A*x=B
	matrix_print(oss, "optimal A*x=B", optimal_check);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	matrix_print(oss, "minimal A*x=B", minimal_check);
	oss << std::endl;
#endif

	return err;
}
int test_over_gelsd(StreamType& oss)
{
	// return value
	int err = 0;

	// overdetermined matrix test
	MatType mat(MatrixGenerator<MatType>()(row_size, col_range));
	VecType vec(VectorGenerator<VecType>()(row_size));

	const int m = traits::matrix_size1(mat);
	const int n = traits::matrix_size2(mat);

#if USE_OPTIMAL_WORKSPACE
	MatType optimalmat(mat);
	VecType optimalvec(vec);
	err += lapack::gelsd(optimalmat, optimalvec, lapack::optimal_workspace());
	VecType optimalanswer(ublas::project(optimalvec, ublas::range(0, n)));
	VecType optimal_check = ublas::prod(mat, optimalanswer);
#endif
#if USE_MINIMAL_WORKSPACE
	MatType minimalmat(mat);
	VecType minimalvec(vec);
	err += lapack::gelsd(minimalmat, minimalvec, lapack::minimal_workspace());
	VecType minimalanswer(ublas::project(minimalvec, ublas::range(0, n)));
	VecType minimal_check = ublas::prod(mat, minimalanswer);
#endif

	matrix_print(oss, "A", mat);
	oss << std::endl;
	vector_print(oss, "B", vec);
	oss << std::endl;

#if USE_OPTIMAL_WORKSPACE
	vector_print(oss, "optimal workspace x", optimalanswer);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	vector_print(oss, "minimal workspace x", minimalanswer);
	oss << std::endl;
#endif
#if USE_OPTIMAL_WORKSPACE
	// check A*x=B
	vector_print(oss, "optimal A*x=B", optimal_check);
	oss << std::endl;
#endif
#if USE_MINIMAL_WORKSPACE
	vector_print(oss, "minimal A*x=B", minimal_check);
	oss << std::endl;
#endif

	return err;
}