<commit_before>/* tests/test-charpoly.C
 * Copyright (C) LinBox
 * Written by bds (starting from test-charpoly.C)
 *
 *
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

/*! @file  tests/test-charpoly.C
 * @ingroup tests
 * @brief tests the characteristic polynomial of sparse and special matrices
 * @warning gcc-4.2 produces bad optimized code there
 * @bug occasionnnaly there is a "SIGFPE, Arithmetic exception." in CRA
 * @bug testRandomCharpoly is not always tested !!
 * @test characteristic polynomial of some matrices (sparse, special)
 */


#include "linbox/linbox-config.h"

#include <iostream>
#include <iomanip>
#include <fstream>

#include <cstdio>

#include "linbox/matrix/sparse-matrix.h"
#include "linbox/blackbox/scalar-matrix.h"
#include "linbox/solutions/charpoly.h"
#include "linbox/util/commentator.h"
#include "linbox/ring/givaro-polynomial.h"
#include "linbox/vector/stream.h"

#include "test-common.h"

using namespace LinBox;


/* Test 1: charpoly of the identity matrix
 *
 * Construct the identity matrix and compute its characteristic polynomial. Confirm
 * that the result is (x-1)^n
 *
 * Z - Integers representation over which to perform computations
 * n - Dimension to which to make matrix
 *
 * Return true on success and false on failure
 */
template <class Dom, class Polynomial>
typename Dom::Element eval (const Dom& D,
			    typename Dom::Element& value,
			    const Polynomial& P,
			    const typename Dom::Element x)
{
	typename Dom::Element tmp = P[P.size()-1];
	for (int i = (int)P.size()-2; i >= 0; --i){
		D.mulin (tmp, x);
		D.addin (tmp, P[(size_t)i]);
	}
	return value = tmp;
}

template <class Dom>
static bool testIdentityCharpoly (Dom &Z, size_t n, bool symmetrizing=false)
{
	typedef typename Dom::Element Element;
	typedef ScalarMatrix<Dom> Blackbox;
// 	typedef GivPolynomialRing<Dom, Givaro::Dense> PolDom;
//  typedef BlasVector<Dom,GivPolynomialRing<Dom, Givaro::Dense> > PolDom;
// 	typedef typename PolDom::Element Polynomial;
	typedef BlasVector <Dom> Vector;
	typedef Vector Polynomial;

	LinBox::commentator().start ("Testing identity Charpoly", "testIdentityCharpoly");

	bool ret = true;

	//PolDom IPD(Z);

	Blackbox A (Z, n, n, Z.one);

	Polynomial phi(Z);

	charpoly (phi, A);

	ostream &report = LinBox::commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
	report << "Characteristic polynomial is: ";
	printPolynomial<Dom, Polynomial> (Z, report, phi);

	// partial check - just that charpoly has right values at 0, 1, -1.
	Element val, val2, neg2, pow2;
	// value at 1 should be zero
	eval(Z, val, phi, Z.one);
	if (! Z.isZero(val) ) ret = false;
	// value at zero should be (-1)^n
	val = (n % 2 == 0) ? Z.one : Z.mOne;
	if (! Z.areEqual(val, phi[0])) ret = false;
	// value at -1 should be (-2)^n
	eval(Z, val2, phi, Z.mOne);
	Z.init(neg2, -2L); Z.assign(pow2, Z.one);
	for (size_t i = 0; i < n; ++i) Z.mulin(pow2, neg2);
	if (! Z.areEqual(val2, pow2)) ret = false;

	if (! ret){
		LinBox::commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
			<< "ERROR: Characteristic polynomial is incorrect" << endl;
	}

	LinBox::commentator().stop (MSG_STATUS (ret), (const char *) 0, "testIdentityCharpoly");

	return ret;
}

/* Test 2: characteristic polynomial of a nilpotent matrix
 *
 * Construct an index-n nilpotent matrix and compute its characteristic
 * polynomial. Confirm that the result is x^n
 *
 * F - Field over which to perform computations
 * n - Dimension to which to make matrix
 *<commit_msg>fixing int constant to fixed size.<commit_after>/* tests/test-charpoly.C
 * Copyright (C) LinBox
 * Written by bds (starting from test-charpoly.C)
 *
 *
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

/*! @file  tests/test-charpoly.C
 * @ingroup tests
 * @brief tests the characteristic polynomial of sparse and special matrices
 * @warning gcc-4.2 produces bad optimized code there
 * @bug occasionnnaly there is a "SIGFPE, Arithmetic exception." in CRA
 * @bug testRandomCharpoly is not always tested !!
 * @test characteristic polynomial of some matrices (sparse, special)
 */


#include "linbox/linbox-config.h"

#include <iostream>
#include <iomanip>
#include <fstream>

#include <cstdio>

#include "linbox/matrix/sparse-matrix.h"
#include "linbox/blackbox/scalar-matrix.h"
#include "linbox/solutions/charpoly.h"
#include "linbox/util/commentator.h"
#include "linbox/ring/givaro-polynomial.h"
#include "linbox/vector/stream.h"

#include "test-common.h"

using namespace LinBox;


/* Test 1: charpoly of the identity matrix
 *
 * Construct the identity matrix and compute its characteristic polynomial. Confirm
 * that the result is (x-1)^n
 *
 * Z - Integers representation over which to perform computations
 * n - Dimension to which to make matrix
 *
 * Return true on success and false on failure
 */
template <class Dom, class Polynomial>
typename Dom::Element eval (const Dom& D,
			    typename Dom::Element& value,
			    const Polynomial& P,
			    const typename Dom::Element x)
{
	typename Dom::Element tmp = P[P.size()-1];
	for (int i = (int)P.size()-2; i >= 0; --i){
		D.mulin (tmp, x);
		D.addin (tmp, P[(size_t)i]);
	}
	return value = tmp;
}

template <class Dom>
static bool testIdentityCharpoly (Dom &Z, size_t n, bool symmetrizing=false)
{
	typedef typename Dom::Element Element;
	typedef ScalarMatrix<Dom> Blackbox;
// 	typedef GivPolynomialRing<Dom, Givaro::Dense> PolDom;
//  typedef BlasVector<Dom,GivPolynomialRing<Dom, Givaro::Dense> > PolDom;
// 	typedef typename PolDom::Element Polynomial;
	typedef BlasVector <Dom> Vector;
	typedef Vector Polynomial;

	LinBox::commentator().start ("Testing identity Charpoly", "testIdentityCharpoly");

	bool ret = true;

	//PolDom IPD(Z);

	Blackbox A (Z, n, n, Z.one);

	Polynomial phi(Z);

	charpoly (phi, A);

	ostream &report = LinBox::commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
	report << "Characteristic polynomial is: ";
	printPolynomial<Dom, Polynomial> (Z, report, phi);

	// partial check - just that charpoly has right values at 0, 1, -1.
	Element val, val2, neg2, pow2;
	// value at 1 should be zero
	eval(Z, val, phi, Z.one);
	if (! Z.isZero(val) ) ret = false;
	// value at zero should be (-1)^n
	val = (n % 2 == 0) ? Z.one : Z.mOne;
	if (! Z.areEqual(val, phi[0])) ret = false;
	// value at -1 should be (-2)^n
	eval(Z, val2, phi, Z.mOne);
	Z.init(neg2, -2_i64); Z.assign(pow2, Z.one);
	for (size_t i = 0; i < n; ++i) Z.mulin(pow2, neg2);
	if (! Z.areEqual(val2, pow2)) ret = false;

	if (! ret){
		LinBox::commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
			<< "ERROR: Characteristic polynomial is incorrect" << endl;
	}

	LinBox::commentator().stop (MSG_STATUS (ret), (const char *) 0, "testIdentityCharpoly");

	return ret;
}

/* Test 2: characteristic polynomial of a nilpotent matrix
 *
 * Construct an index-n nilpotent matrix and compute its characteristic
 * polynomial. Confirm that the result is x^n
 *
 * F - Field over which to perform computations
 * n - Dimension to which to make matrix
 *
{'fraction_non_alphanumeric': 0.12387231089521165, 'fraction_numerical': 0.010409437890353921, 'mean_word_length': 4.101474926253688, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5899058', 'n_tokens_mistral': 2912, 'n_tokens_neox': 2756, 'n_words': 1007}