Polymath/tests/tests.h

85 lines
3.1 KiB
C++

#ifndef TESTS_H
#define TESTS_H
#include "Polymath.h"
#include <Python.h>
template <typename T>
int precision_per_type()
{
if(std::is_same<T,double>::value || std::is_same<T,std::complex<double>>::value)
return 10;
else if(std::is_same<T,float>::value || std::is_same<T,std::complex<float>>::value)
return 2;
else
return 2;
}
template <typename T>
std::string python_type_per_type()
{
return std::string("np.complex128");
if(std::is_same<T,double>::value)
{
return std::string("np.double");
}
else if(std::is_same<T,std::complex<double>>::value)
{
return std::string("np.complex128");
}
else if(std::is_same<T,float>::value)
{
return std::string("np.float32");
}
else if(std::is_same<T,std::complex<float>>::value)
{
return std::string("np.complex64");
}
else
{
return std::string("np.complex128");
}
}
template <typename T>
bool TestInverse(int len, bool print)
{
Poly::Matrix<T> mat_d = Poly::RandomMatrix<T>(len,len,0,10,std::random_device{}());
if(print) std::cout<<mat_d<<std::endl;
if(print) std::cout<<mat_d.asString(32,'[',']',',')<<std::endl;
int prec = precision_per_type<T>();
auto mat_d_i = mat_d.getInverse();
PyObject *main = PyImport_AddModule("__main__");
PyRun_SimpleString(std::string("data={}").c_str());
PyRun_SimpleString(std::string("data['a']=np.matrix(" + mat_d.asString(32,'[',']',',') + ",dtype="+python_type_per_type<T>()+")").c_str());
PyRun_SimpleString(std::string("data['b_c']=np.matrix(" + mat_d_i.asString(32,'[',']',',') + ",dtype="+std::string("np.complex128")+")").c_str());
PyRun_SimpleString(std::string("data['b_p']=np.linalg.inv(data['a'])").c_str());
if(print) std::cout << mat_d.columns() << std::endl;
if(print) PyRun_SimpleString(std::string("print('Cond num: ', np.linalg.cond(data['a']))").c_str());
if(print) PyRun_SimpleString(std::string("print('Cond num: ', np.linalg.cond(data['b_c']))").c_str());
if(print) PyRun_SimpleString(std::string("print('Cond num: ', np.linalg.cond(data['b_c']))").c_str());
if(print) PyRun_SimpleString("print(data['a'])");
if(print) PyRun_SimpleString("print(data['b_c'])");
if(print) PyRun_SimpleString("print(data['b_p'])");
if(print) PyRun_SimpleString("print(abs(data['b_c']-data['b_p']))");
PyRun_SimpleString("data['fb_p']=((data['b_p']).flatten().tolist())[0]");
PyRun_SimpleString("data['fb_c']=((data['b_c']).flatten().tolist())[0]");
PyRun_SimpleString(std::string("res=list(set([compare_floats(data['fb_p'][i],data['fb_c'][i],1e-"+ std::to_string(prec) +") for i in range(len(data['fb_p']))]))").c_str());
PyRun_SimpleString(std::string("res = ((len(res) == 1) and res[0])").c_str());
if(print) PyRun_SimpleString("print('Is close: ',res)");
// getchar();
PyObject *globals = PyModule_GetDict(main);
PyObject *a = PyDict_GetItemString(globals, "res");
bool ret = PyObject_IsTrue(a);
PyRun_SimpleString("del data");
PyRun_SimpleString("del res");
return ret;
}
int RunTests();
#endif // TESTS_H