<commit_before>// <NAME> 2012--2013
//
// Test functions from
// <NAME>, <NAME> and <NAME>,
// "Testing unconstrained optimization software",
// Transactions on Mathematical Software 7(1):17-41, 1981.
// http://www.caam.rice.edu/~zhang/caam454/nls/MGH.pdf
//
#include <cmath>
#include <iostream>
#include <memory>
#include <random>
#include <sstream>

#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <spii/google_test_compatibility.h>

#include <spii/auto_diff_term.h>
#include <spii/solver.h>

using namespace spii;

std::stringstream global_string_stream;
void info_log_function(const std::string& str)
{
	global_string_stream << str << "\n";
}

std::unique_ptr<Solver> create_solver()
{
	std::unique_ptr<Solver> solver(new NewtonSolver);
	// Use default solver settings.

	solver->log_function = info_log_function;
	//solver->factorization_method = Solver::ITERATIVE;

	return std::move(solver);
}

int cumulative_iterations   = 0;
int cumulative_evalutations = 0;
double cumulative_time      = 0;

template<typename Functor, int dimension>
double run_test(double* var, const Solver* solver = 0)
{
	Function f;
	f.add_variable(var, dimension);
	f.add_term(std::make_shared<AutoDiffTerm<Functor, dimension>>(), var);

	auto own_solver = create_solver();
	if (solver == 0) {
		solver = own_solver.get();
	}
	SolverResults results;
	global_string_stream.str("");
	solver->solve(f, &results);
	INFO(global_string_stream.str());
	INFO(results);

	std::stringstream sout;
	for (int i = 0; i < dimension; ++i) {
		sout << "x" << i + 1 << " = " << var[i] << ",  ";
	}
	INFO(sout.str());

	EXPECT_TRUE(results.exit_condition == SolverResults::ARGUMENT_TOLERANCE ||
	            results.exit_condition == SolverResults::FUNCTION_TOLERANCE ||
	            results.exit_condition == SolverResults::GRADIENT_TOLERANCE);

	cumulative_evalutations += f.evaluations_with_gradient;
	cumulative_time         += results.total_time - results.log_time;
	INFO("Cumulative evaluations: " << cumulative_evalutations);
	INFO("Cumulative time       : " << cumulative_time);

	return f.evaluate();
}

#include "suite_more_et_al.h"
#include "suite_test_opt.h"
#include "suite_uctp.h"<commit_msg>Test both factorization methods.<commit_after>// <NAME> 2012--2013
//
// Test functions from
// <NAME>, <NAME> and <NAME>,
// "Testing unconstrained optimization software",
// Transactions on Mathematical Software 7(1):17-41, 1981.
// http://www.caam.rice.edu/~zhang/caam454/nls/MGH.pdf
//
#include <cmath>
#include <iostream>
#include <memory>
#include <random>
#include <sstream>

#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <spii/google_test_compatibility.h>

#include <spii/auto_diff_term.h>
#include <spii/solver.h>

using namespace spii;

std::stringstream global_string_stream;
void info_log_function(const std::string& str)
{
	global_string_stream << str << "\n";
}

std::unique_ptr<Solver> create_solver()
{
	std::unique_ptr<NewtonSolver> solver(new NewtonSolver);
	solver->log_function = info_log_function;

	return std::move(solver);
}

int cumulative_iterations   = 0;
int cumulative_evalutations = 0;
double cumulative_time      = 0;

template<typename Functor, int dimension>
double run_test_with_factorization_method(double* var, Solver* solver)
{
	Function f;
	f.add_variable(var, dimension);
	f.add_term(std::make_shared<AutoDiffTerm<Functor, dimension>>(), var);

	SolverResults results;
	global_string_stream.str("");
	solver->solve(f, &results);
	INFO(global_string_stream.str());
	INFO(results);

	std::stringstream sout;
	for (int i = 0; i < dimension; ++i) {
		sout << "x" << i + 1 << " = " << var[i] << ",  ";
	}
	INFO(sout.str());

	EXPECT_TRUE(results.exit_condition == SolverResults::ARGUMENT_TOLERANCE ||
	            results.exit_condition == SolverResults::FUNCTION_TOLERANCE ||
	            results.exit_condition == SolverResults::GRADIENT_TOLERANCE);

	cumulative_evalutations += f.evaluations_with_gradient;
	cumulative_time         += results.total_time - results.log_time;
	INFO("Cumulative evaluations: " << cumulative_evalutations);
	INFO("Cumulative time       : " << cumulative_time);

	return f.evaluate();
}

template<typename Functor, int dimension>
double run_test(double* var, Solver* solver_input = 0)
{
	auto own_solver = create_solver();
	if (solver_input == 0) {
		solver_input = own_solver.get();
	}
	auto solver = dynamic_cast<NewtonSolver*>(solver_input);
	spii_assert(solver);

	// First, test that the iterative factorization method
	// achieves convergence. 
	std::vector<double> var_copy(var, var + dimension);
	solver->factorization_method = NewtonSolver::ITERATIVE;
	run_test_with_factorization_method<Functor, dimension>(&var_copy[0], solver);

	// Then, test the BKP factorization and return the results using
	// this method.
	solver->factorization_method = NewtonSolver::BKP;
	return run_test_with_factorization_method<Functor, dimension>(var, solver);
}

#include "suite_more_et_al.h"
#include "suite_test_opt.h"
#include "suite_uctp.h"
{'fraction_non_alphanumeric': 0.1407095610342754, 'fraction_numerical': 0.011425135297654841, 'mean_word_length': 5.276729559748428, 'pattern_counts': {'":': 0, '<': 82, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1333463', 'n_tokens_mistral': 1822, 'n_tokens_neox': 1703, 'n_words': 344}