Merge pull request #54 from jacobly0/fix-transpose

Fix swapped matrix transpose, multiplication, opposite, and clone dimensions
This commit is contained in:
EmilieNumworks
2017-09-01 00:57:20 -07:00
committed by GitHub
21 changed files with 139 additions and 129 deletions

View File

@@ -8,7 +8,7 @@ namespace Poincare {
class ExpressionMatrix : public Matrix {
public:
ExpressionMatrix(MatrixData * matrixData);
ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int m_numberOfColumns, int m_numberOfRows, bool cloneOperands);
ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands);
~ExpressionMatrix();
ExpressionMatrix(const Matrix& other) = delete;
ExpressionMatrix(Matrix&& other) = delete;

View File

@@ -12,7 +12,7 @@ class Complex;
class MatrixData {
public:
MatrixData(ListData * listData, bool clone);
MatrixData(Expression ** newOperands, int numberOfOperands, int m_numberOfColumns, int m_numberOfRows, bool cloneOperands);
MatrixData(Expression ** newOperands, int numberOfOperands, int m_numberOfRows, int m_numberOfColumns, bool cloneOperands);
~MatrixData();
MatrixData(const MatrixData& other) = delete;
MatrixData(MatrixData&& other) = delete;

View File

@@ -18,8 +18,8 @@ ComplexMatrix<T>::ComplexMatrix(const Complex<T> * complexes, int numberOfRows,
m_numberOfColumns(numberOfColumns)
{
assert(complexes != nullptr);
m_values = new Complex<T>[numberOfColumns*numberOfRows];
for (int i = 0; i < numberOfColumns*numberOfRows; i++) {
m_values = new Complex<T>[numberOfRows*numberOfColumns];
for (int i = 0; i < numberOfRows*numberOfColumns; i++) {
m_values[i] = complexes[i];
}
}
@@ -31,7 +31,7 @@ ComplexMatrix<T>::~ComplexMatrix() {
template<typename T>
T ComplexMatrix<T>::toScalar() const {
if (m_numberOfColumns != 1 || m_numberOfRows != 1) {
if (m_numberOfRows != 1 || m_numberOfColumns != 1) {
return NAN;
}
if (m_values[0].b() != 0) {
@@ -64,7 +64,7 @@ template<typename T>
ComplexMatrix<T> * ComplexMatrix<T>::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(newOperands != nullptr);
return new ComplexMatrix((Complex<T> *)newOperands[0], m_numberOfColumns, m_numberOfRows);
return new ComplexMatrix((Complex<T> *)newOperands[0], m_numberOfRows, m_numberOfColumns);
}
template<typename T>
@@ -87,8 +87,8 @@ Evaluation<T> * ComplexMatrix<T>::createIdentity(int dim) {
template<typename T>
template <class U>
Evaluation<U> * ComplexMatrix<T>::templatedEvaluate(Context& context, Expression::AngleUnit angleUnit) const {
Complex<U> * values = new Complex<U>[m_numberOfColumns*m_numberOfRows];
for (int i = 0; i < m_numberOfColumns*m_numberOfRows; i++) {
Complex<U> * values = new Complex<U>[m_numberOfRows*m_numberOfColumns];
for (int i = 0; i < m_numberOfRows*m_numberOfColumns; i++) {
values[i] = Complex<U>::Cartesian(m_values[i].a(), m_values[i].b());
}
Evaluation<U> * result = new ComplexMatrix<U>(values, m_numberOfRows, m_numberOfColumns);

View File

@@ -31,7 +31,7 @@ const Expression * Evaluation<T>::operand(int i) const {
template<typename T>
Evaluation<T> * Evaluation<T>::createTrace() const {
if (numberOfColumns() != numberOfRows()) {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
@@ -45,7 +45,7 @@ Evaluation<T> * Evaluation<T>::createTrace() const {
template<typename T>
// TODO: implement determinant for complex matrix?
Evaluation<T> * Evaluation<T>::createDeterminant() const {
if (numberOfColumns() != numberOfRows()) {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
@@ -107,7 +107,7 @@ Evaluation<T> * Evaluation<T>::createDeterminant() const {
template<typename T>
Evaluation<T> * Evaluation<T>::createInverse() const {
if (numberOfColumns() != numberOfRows()) {
if (numberOfRows() != numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
int dim = numberOfRows();
@@ -175,6 +175,7 @@ Evaluation<T> * Evaluation<T>::createInverse() const {
delete[] inv[i];
}
delete[] inv;
// Intentionally swapping dimensions for inverse, although it doesn't make a difference because it is square
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfColumns(), numberOfRows());
delete[] operands;
return matrix;
@@ -188,7 +189,8 @@ Evaluation<T> * Evaluation<T>::createTranspose() const {
operands[j*numberOfRows()+i] = *(complexOperand(i*numberOfColumns()+j));
}
}
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfRows(), numberOfColumns());
// Intentionally swapping dimensions for transpose
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, numberOfColumns(), numberOfRows());
delete[] operands;
return matrix;
}

View File

@@ -16,9 +16,9 @@ ExpressionMatrix::ExpressionMatrix(MatrixData * matrixData) :
{
}
ExpressionMatrix::ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int numberOfColumns, int numberOfRows, bool cloneOperands)
ExpressionMatrix::ExpressionMatrix(Expression ** newOperands, int numberOfOperands, int numberOfRows, int numberOfColumns, bool cloneOperands)
{
m_matrixData = new MatrixData(newOperands, numberOfOperands, numberOfColumns, numberOfRows, cloneOperands);
m_matrixData = new MatrixData(newOperands, numberOfOperands, numberOfRows, numberOfColumns, cloneOperands);
}
ExpressionMatrix::~ExpressionMatrix() {
@@ -60,7 +60,7 @@ Expression::Type ExpressionMatrix::type() const {
Expression * ExpressionMatrix::cloneWithDifferentOperands(Expression** newOperands,
int numberOfOperands, bool cloneOperands) const {
assert(newOperands != nullptr);
return new ExpressionMatrix(newOperands, numberOfOperands, numberOfColumns(), numberOfRows(), cloneOperands);
return new ExpressionMatrix(newOperands, numberOfOperands, numberOfRows(), numberOfColumns(), cloneOperands);
}
template<typename T>

View File

@@ -23,13 +23,13 @@ MatrixData::MatrixData(ListData * listData, bool clone) :
}
}
MatrixData::MatrixData(Expression ** newOperands, int numberOfOperands, int numberOfColumns, int numberOfRows, bool cloneOperands) :
MatrixData::MatrixData(Expression ** newOperands, int numberOfOperands, int numberOfRows, int numberOfColumns, bool cloneOperands) :
m_numberOfRows(numberOfRows),
m_numberOfColumns(numberOfColumns)
{
assert(newOperands != nullptr);
m_operands = new Expression *[m_numberOfRows*m_numberOfColumns];
for (int i = 0; i < m_numberOfColumns*m_numberOfRows; i++) {
for (int i = 0; i < m_numberOfRows*m_numberOfColumns; i++) {
if (cloneOperands) {
m_operands[i] = i < numberOfOperands ? newOperands[i]->clone() : defaultExpression();
} else {
@@ -44,7 +44,7 @@ Complex<double> * MatrixData::defaultExpression() {
}
MatrixData::~MatrixData() {
for (int i=0; i<m_numberOfColumns*m_numberOfRows; i++) {
for (int i=0; i<m_numberOfRows*m_numberOfColumns; i++) {
// Warning: avoid deleting the defaultExpression
if (m_operands[i] != defaultExpression()) {
delete m_operands[i];

View File

@@ -62,7 +62,7 @@ Evaluation<T> * Multiplication::computeOnMatrices(Evaluation<T> * m, Evaluation<
operands[i*n->numberOfColumns()+j] = Complex<T>::Cartesian(a, b);
}
}
Evaluation<T> * result = new ComplexMatrix<T>(operands, n->numberOfColumns(), m->numberOfRows());
Evaluation<T> * result = new ComplexMatrix<T>(operands, m->numberOfRows(), n->numberOfColumns());
delete[] operands;
return result;
}

View File

@@ -54,7 +54,7 @@ Evaluation<T> * Opposite::computeOnMatrix(Evaluation<T> * m) {
Complex<T> entry = *(m->complexOperand(i));
operands[i] = Complex<T>::Cartesian(-entry.a(), -entry.b());
}
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, m->numberOfColumns(), m->numberOfRows());
Evaluation<T> * matrix = new ComplexMatrix<T>(operands, m->numberOfRows(), m->numberOfColumns());
delete[] operands;
return matrix;
}

View File

@@ -65,7 +65,7 @@ Complex<T> Power::compute(const Complex<T> c, const Complex<T> d) {
}
template<typename T> Evaluation<T> * Power::templatedComputeOnComplexMatrixAndComplex(Evaluation<T> * m, const Complex<T> * d) const {
if (m->numberOfColumns() != m->numberOfRows()) {
if (m->numberOfRows() != m->numberOfColumns()) {
return new Complex<T>(Complex<T>::Float(NAN));
}
T power = d->toScalar();

View File

@@ -8,26 +8,26 @@ using namespace Poincare;
QUIZ_CASE(poincare_addition_evaluate) {
Complex<float> a[1] = {Complex<float>::Float(3.0f)};
assert_parsed_expression_evaluate_to("1+2", a, 1);
assert_parsed_expression_evaluates_to("1+2", a);
Complex<double> b[1] = {Complex<double>::Cartesian(6.0, 2.0)};
assert_parsed_expression_evaluate_to("2+I+4+I", b, 1);
assert_parsed_expression_evaluates_to("2+I+4+I", b);
#if MATRICES_ARE_DEFINED
Complex<float> c[6] = {Complex<float>::Float(4.0f), Complex<float>::Float(5.0f), Complex<float>::Float(6.0f), Complex<float>::Float(7.0f), Complex<float>::Float(8.0f), Complex<float>::Float(9.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]+3", c, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]+3", c, 3, 2);
Complex<double> d[6] = {Complex<double>::Cartesian(4.0, 1.0), Complex<double>::Cartesian(5.0, 2.0), Complex<double>::Cartesian(6.0, 1.0), Complex<double>::Cartesian(7.0, 1.0), Complex<double>::Cartesian(8.0, 1.0), Complex<double>::Cartesian(9.0, 1.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]+3+I", d, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]+3+I", d, 3, 2);
assert_parsed_expression_evaluate_to("3+[[1,2][3,4][5,6]]", c, 6);
assert_parsed_expression_evaluates_to("3+[[1,2][3,4][5,6]]", c, 3, 2);
assert_parsed_expression_evaluate_to("3+I+[[1,2+I][3,4][5,6]]", d, 6);
assert_parsed_expression_evaluates_to("3+I+[[1,2+I][3,4][5,6]]", d, 3, 2);
Complex<float> e[6] = {Complex<float>::Float(2.0f), Complex<float>::Float(4.0f), Complex<float>::Float(6.0f), Complex<float>::Float(8.0f), Complex<float>::Float(10.0f), Complex<float>::Float(12.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]+[[1,2][3,4][5,6]]", e, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]+[[1,2][3,4][5,6]]", e, 3, 2);
Complex<double> f[6] = {Complex<double>::Cartesian(2.0, 0.0), Complex<double>::Cartesian(4.0, 2.0), Complex<double>::Cartesian(6.0, 0.0), Complex<double>::Cartesian(8.0, 0.0), Complex<double>::Cartesian(10.0, 0.0), Complex<double>::Cartesian(12.0, 0.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]+[[1,2+I][3,4][5,6]]", f, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]+[[1,2+I][3,4][5,6]]", f, 3, 2);
#endif
}

View File

@@ -9,27 +9,27 @@ using namespace Poincare;
QUIZ_CASE(poincare_fraction_evaluate) {
Complex<float> a[1] = {Complex<float>::Float(0.5f)};
assert_parsed_expression_evaluate_to("1/2", a, 1);
assert_parsed_expression_evaluates_to("1/2", a);
Complex<double> b[1] = {Complex<double>::Cartesian(13.0/17.0, 1.0/17.0)};
assert_parsed_expression_evaluate_to("(3+I)/(4+I)", b, 1);
assert_parsed_expression_evaluates_to("(3+I)/(4+I)", b);
#if MATRICES_ARE_DEFINED
Complex<float> c[6] = {Complex<float>::Float(0.5f), Complex<float>::Float(1.0f), Complex<float>::Float(1.5f), Complex<float>::Float(2.0f), Complex<float>::Float(2.5f), Complex<float>::Float(3.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]/2", c, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]/2", c, 3, 2);
Complex<double> d[6] = {Complex<double>::Cartesian(4.0/17.0, -1.0/17.0), Complex<double>::Cartesian(9.0/17.0, 2.0/17.0), Complex<double>::Cartesian(12.0/17.0, -3.0/17.0), Complex<double>::Cartesian(16.0/17.0, -4.0/17.0), Complex<double>::Cartesian(20.0/17.0, -5.0/17.0), Complex<double>::Cartesian(24.0/17.0, -6.0/17.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]/(4+I)", d, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]/(4+I)", d, 3, 2);
Complex<float> e[4] = {Complex<float>::Float(2.0f), Complex<float>::Float(-1.0f), Complex<float>::Float(1.0f), Complex<float>::Float(0.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4]]/[[3,4][5,6]]", e, 4);
assert_parsed_expression_evaluates_to("[[1,2][3,4]]/[[3,4][5,6]]", e, 2, 2);
Complex<double> f[4] = {Complex<double>::Float(-9.0), Complex<double>::Float(6.0), Complex<double>::Float(15.0/2.0), Complex<double>::Float(-9.0/2.0)};
assert_parsed_expression_evaluate_to("3/[[3,4][5,6]]", f, 4);
assert_parsed_expression_evaluates_to("3/[[3,4][5,6]]", f, 2, 2);
// TODO: add this test when inverse of complex matrix is implemented
/* Complex<double> g[4] = {Complex<double>::Cartesian(-9.0, -12.0), Complex<double>::Cartesian(6.0, 8.0), Complex<double>::Cartesian(15.0/2.0, 10.0), Complex<double>::Cartesian(-9.0/2.0, -6.0)};
assert_parsed_expression_evaluate_to("(3+4i)/[[1,2+i][3,4][5,6]]", g, 4);*/
assert_parsed_expression_evaluates_to("(3+4i)/[[1,2+i][3,4][5,6]]", g, 2, 2);*/
#endif
}

View File

@@ -150,125 +150,127 @@ QUIZ_CASE(poincare_parse_function) {
QUIZ_CASE(poincare_function_evaluate) {
Complex<double> a0[1] = {Complex<double>::Float(1.0)};
assert_parsed_expression_evaluate_to("abs(-1)", a0, 1);
assert_parsed_expression_evaluates_to("abs(-1)", a0);
Complex<float> a1[1] = {Complex<float>::Float(std::sqrt(3.0f*3.0f+2.0f*2.0f))};
assert_parsed_expression_evaluate_to("abs(3+2I)", a1, 1);
assert_parsed_expression_evaluates_to("abs(3+2I)", a1);
Complex<double> a2[4] = {Complex<double>::Float(1.0), Complex<double>::Float(2.0), Complex<double>::Float(3.0), Complex<double>::Float(4.0)};
assert_parsed_expression_evaluate_to("abs([[1,-2][3,-4]])", a2, 4);
assert_parsed_expression_evaluates_to("abs([[1,-2][3,-4]])", a2, 2, 2);
Complex<float> a3[4] = {Complex<float>::Float(std::sqrt(3.0f*3.0f+2.0f*2.0f)), Complex<float>::Float(std::sqrt(3.0f*3.0f+4.0f*4.0f)), Complex<float>::Float(std::sqrt(5.0f*5.0f+2.0f*2.0f)), Complex<float>::Float(std::sqrt(3.0f*3.0f+2.0f*2.0f))};
assert_parsed_expression_evaluate_to("abs([[3+2I,3+4I][5+2I,3+2I]])", a3, 4);
assert_parsed_expression_evaluates_to("abs([[3+2I,3+4I][5+2I,3+2I]])", a3, 2, 2);
Complex<double> b[1] = {Complex<double>::Float(210.0)};
assert_parsed_expression_evaluate_to("binomial(10, 4)", b, 1);
assert_parsed_expression_evaluates_to("binomial(10, 4)", b);
Complex<float> c[1] = {Complex<float>::Float(1.0f)};
assert_parsed_expression_evaluate_to("ceil(0.2)", c, 1);
assert_parsed_expression_evaluates_to("ceil(0.2)", c);
Complex<double> d[1] = {Complex<double>::Float(2.0)};
assert_parsed_expression_evaluate_to("diff(2*x, 2)", d, 1);
assert_parsed_expression_evaluates_to("diff(2*x, 2)", d);
#if MATRICES_ARE_DEFINED
Complex<float> e[1] = {Complex<float>::Float(126.0f)};
assert_parsed_expression_evaluate_to("det([[1,23,3][4,5,6][7,8,9]])", e, 1);
assert_parsed_expression_evaluates_to("det([[1,23,3][4,5,6][7,8,9]])", e);
#endif
Complex<double> f[1] = {Complex<double>::Float(2.0)};
assert_parsed_expression_evaluate_to("floor(2.3)", f, 1);
assert_parsed_expression_evaluates_to("floor(2.3)", f);
Complex<float> g[1] = {Complex<float>::Float(0.3f)};
assert_parsed_expression_evaluate_to("frac(2.3)", g, 1);
assert_parsed_expression_evaluates_to("frac(2.3)", g);
Complex<double> h[1] = {Complex<double>::Float(2.0)};
assert_parsed_expression_evaluate_to("gcd(234,394)", h, 1);
assert_parsed_expression_evaluates_to("gcd(234,394)", h);
Complex<float> i[1] = {Complex<float>::Float(3.0f)};
assert_parsed_expression_evaluate_to("im(2+3I)", i, 1);
assert_parsed_expression_evaluates_to("im(2+3I)", i);
Complex<double> j[1] = {Complex<double>::Float(3.0/2.0)};
assert_parsed_expression_evaluate_to("int(x, 1, 2)", j, 1);
assert_parsed_expression_evaluates_to("int(x, 1, 2)", j);
Complex<float> k[1] = {Complex<float>::Float(46098.0f)};
assert_parsed_expression_evaluate_to("lcm(234,394)", k, 1);
assert_parsed_expression_evaluates_to("lcm(234,394)", k);
Complex<double> l[1] = {Complex<double>::Float(std::log(2.0))};
assert_parsed_expression_evaluate_to("ln(2)", l, 1);
assert_parsed_expression_evaluates_to("ln(2)", l);
Complex<float> m[1] = {Complex<float>::Float(std::log10(2.0f))};
assert_parsed_expression_evaluate_to("log(2)", m, 1);
assert_parsed_expression_evaluates_to("log(2)", m);
Complex<double> n[1] = {Complex<double>::Float(5040.0)};
assert_parsed_expression_evaluate_to("permute(10, 4)", n, 1);
assert_parsed_expression_evaluates_to("permute(10, 4)", n);
Complex<float> o[1] = {Complex<float>::Float(604800.0f)};
assert_parsed_expression_evaluate_to("product(n, 4, 10)", o, 1);
assert_parsed_expression_evaluates_to("product(n, 4, 10)", o);
Complex<double> p[1] = {Complex<double>::Float(2.0)};
assert_parsed_expression_evaluate_to("re(2+I)", p, 1);
assert_parsed_expression_evaluates_to("re(2+I)", p);
Complex<float> q[1] = {Complex<float>::Float(9.0f)};
assert_parsed_expression_evaluate_to("rem(29, 10)", q, 1);
assert_parsed_expression_evaluates_to("rem(29, 10)", q);
Complex<double> r[1] = {Complex<double>::Float(std::pow(2.0, 1.0/3.0))};
assert_parsed_expression_evaluate_to("root(2,3)", r, 1);
assert_parsed_expression_evaluates_to("root(2,3)", r);
Complex<float> s[1] = {Complex<float>::Float(std::sqrt(2.0f))};
assert_parsed_expression_evaluate_to("R(2)", s, 1);
assert_parsed_expression_evaluates_to("R(2)", s);
Complex<double> t[1] = {Complex<double>::Float(49.0)};
assert_parsed_expression_evaluate_to("sum(n, 4, 10)", t, 1);
assert_parsed_expression_evaluates_to("sum(n, 4, 10)", t);
#if MATRICES_ARE_DEFINED
Complex<float> u[1] = {Complex<float>::Float(15.0f)};
assert_parsed_expression_evaluate_to("trace([[1,2,3][4,5,6][7,8,9]])", u, 1);
assert_parsed_expression_evaluates_to("trace([[1,2,3][4,5,6][7,8,9]])", u);
#endif
Complex<double> v[2] = {Complex<double>::Float(0.1 - std::sqrt(1.0/100.0)), Complex<double>::Float(0.1 + std::sqrt(1.0/100.0))};
assert_parsed_expression_evaluate_to("confidence(0.1, 100)", v, 2);
assert_parsed_expression_evaluates_to("confidence(0.1, 100)", v, 2);
#if MATRICES_ARE_DEFINED
Complex<float> w[2] = {Complex<float>::Float(2.0f), Complex<float>::Float(3.0f)};
assert_parsed_expression_evaluate_to("dim([[1,2,3][4,5,-6]])", w, 2);
assert_parsed_expression_evaluates_to("dim([[1,2,3][4,5,-6]])", w, 2);
#endif
Complex<double> x[1] = {Complex<double>::Cartesian(3.0, -2.0)};
assert_parsed_expression_evaluate_to("conj(3+2*I)", x, 1);
assert_parsed_expression_evaluates_to("conj(3+2*I)", x);
#if MATRICES_ARE_DEFINED
Complex<float> y[9] = {Complex<float>::Float(-31.0f/24.0f), Complex<float>::Float(-1.0f/12.0f), Complex<float>::Float(3.0f/8.0f), Complex<float>::Float(13.0f/12.0f), Complex<float>::Float(1.0f/6.0f), Complex<float>::Float(-1.0f/4.0f), Complex<float>::Float(1.0f/24.0f),Complex<float>::Float(-1.0f/12.0f), Complex<float>::Float(1.0f/24.0f)};
assert_parsed_expression_evaluate_to("inverse([[1,2,3][4,5,-6][7,8,9]])", y, 9);
assert_parsed_expression_evaluates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", y, 3, 3);
#endif
Complex<double> z[2] = {Complex<double>::Float(0.1-std::sqrt(1.0/100.0)), Complex<double>::Float(0.1+std::sqrt(1.0/100.0))};
assert_parsed_expression_evaluate_to("prediction(0.1, 100)", z, 2);
assert_parsed_expression_evaluates_to("prediction(0.1, 100)", z, 2);
Complex<float> aa[2] = {Complex<float>::Float(0.1f-1.96f*std::sqrt((0.1f*(1.0f-0.1f))/100.0f)), Complex<float>::Float(0.1f+1.96f*std::sqrt((0.1f*(1.0f-0.1f))/100.0f))};
assert_parsed_expression_evaluate_to("prediction95(0.1, 100)", aa, 2);
assert_parsed_expression_evaluates_to("prediction95(0.1, 100)", aa, 2);
Complex<double> ab[1] = {Complex<double>::Cartesian(-100.0, -540.0)};
assert_parsed_expression_evaluate_to("product(2+n*I, 1, 5)", ab, 1);
assert_parsed_expression_evaluates_to("product(2+n*I, 1, 5)", ab);
Complex<float> ac[1] = {Complex<float>::Cartesian(1.4593656008f, 0.1571201229f)};
assert_parsed_expression_evaluate_to("root(3+I, 3)", ac, 1);
assert_parsed_expression_evaluates_to("root(3+I, 3)", ac);
Complex<double> ad[1] = {Complex<double>::Cartesian(1.38200696233, -0.152442779)};
assert_parsed_expression_evaluate_to("root(3, 3+I)", ad, 1);
assert_parsed_expression_evaluates_to("root(3, 3+I)", ad);
Complex<float> ae[1] = {Complex<float>::Cartesian(1.75532f, 0.28485f)};
assert_parsed_expression_evaluate_to("R(3+I)", ae, 1);
assert_parsed_expression_evaluates_to("R(3+I)", ae);
Complex<double> af[1] = {Complex<double>::Cartesian(10.0, 15.0)};
assert_parsed_expression_evaluate_to("sum(2+n*I,1,5)", af, 1);
assert_parsed_expression_evaluates_to("sum(2+n*I,1,5)", af);
#if MATRICES_ARE_DEFINED
Complex<double> ag[9] = {Complex<double>::Float(1.0), Complex<double>::Float(4.0), Complex<double>::Float(7.0), Complex<double>::Float(2.0), Complex<double>::Float(5.0), Complex<double>::Float(8.0), Complex<double>::Float(3.0), Complex<double>::Float(-6.0), Complex<double>::Float(9.0)};
assert_parsed_expression_evaluate_to("transpose([[1,2,3][4,5,-6][7,8,9]])", ag, 9);
assert_parsed_expression_evaluates_to("transpose([[1,2,3][4,5,-6][7,8,9]])", ag, 3, 3);
assert_parsed_expression_evaluates_to("transpose([[1,7,5][4,2,8]])", ag, 3, 2);
assert_parsed_expression_evaluates_to("transpose([[1,2][4,5][7,8]])", ag, 2, 3);
#endif
Complex<float> ah[1] = {Complex<float>::Float(2.325f)};
assert_parsed_expression_evaluate_to("round(2.3245,3)", ah, 1);
assert_parsed_expression_evaluates_to("round(2.3245,3)", ah);
Complex<double> ai[1] = {Complex<double>::Float(720.0f)};
assert_parsed_expression_evaluate_to("6!", ai, 1);
assert_parsed_expression_evaluates_to("6!", ai);
}

View File

@@ -9,7 +9,7 @@
using namespace Poincare;
template<typename T>
void assert_parsed_expression_evaluate_to(const char * expression, Complex<T> * results, int numberOfEntries, Expression::AngleUnit angleUnit) {
void assert_parsed_expression_evaluates_to(const char * expression, Complex<T> * results, int numberOfRows, int numberOfColumns, Expression::AngleUnit angleUnit) {
char buffer[200];
strlcpy(buffer, expression, 200);
for (size_t i=0; i<strlen(buffer); i++) {
@@ -32,7 +32,9 @@ void assert_parsed_expression_evaluate_to(const char * expression, Complex<T> *
GlobalContext globalContext;
Expression * a = Expression::parse(buffer);
Evaluation<T> * m = a->evaluate<T>(globalContext, angleUnit);
for (int i = 0; i < numberOfEntries; i++) {
assert(m->numberOfRows() == numberOfRows);
assert(m->numberOfColumns() == numberOfColumns);
for (int i = 0; i < m->numberOfOperands(); i++) {
assert(std::fabs(m->complexOperand(i)->a() - results[i].a()) < 0.0001f);
assert(std::fabs(m->complexOperand(i)->b() - results[i].b()) < 0.0001f);
}
@@ -40,5 +42,5 @@ void assert_parsed_expression_evaluate_to(const char * expression, Complex<T> *
delete m;
}
template void assert_parsed_expression_evaluate_to<float>(char const*, Poincare::Complex<float>*, int, Poincare::Expression::AngleUnit);
template void assert_parsed_expression_evaluate_to<double>(char const*, Poincare::Complex<double>*, int, Poincare::Expression::AngleUnit);
template void assert_parsed_expression_evaluates_to<float>(char const*, Poincare::Complex<float>*, int, int, Poincare::Expression::AngleUnit);
template void assert_parsed_expression_evaluates_to<double>(char const*, Poincare::Complex<double>*, int, int, Poincare::Expression::AngleUnit);

View File

@@ -4,4 +4,8 @@ constexpr Poincare::Expression::AngleUnit Degree = Poincare::Expression::AngleUn
constexpr Poincare::Expression::AngleUnit Radian = Poincare::Expression::AngleUnit::Radian;
template<typename T>
void assert_parsed_expression_evaluate_to(const char * expression, Poincare::Complex<T> * results, int numberOfEntries, Poincare::Expression::AngleUnit angleUnit = Degree);
void assert_parsed_expression_evaluates_to(const char * expression, Poincare::Complex<T> * results, int numberOfRows, int numberOfColumns = 1, Poincare::Expression::AngleUnit angleUnit = Degree);
template<typename T>
void assert_parsed_expression_evaluates_to(const char * expression, Poincare::Complex<T> * results, Poincare::Expression::AngleUnit angleUnit = Degree) {
assert_parsed_expression_evaluates_to(expression, results, 1, 1, angleUnit);
}

View File

@@ -8,9 +8,9 @@ using namespace Poincare;
QUIZ_CASE(poincare_matrix_evaluate) {
#if MATRICES_ARE_DEFINED
Complex<float> a[6] = {Complex<float>::Float(1.0f), Complex<float>::Float(2.0f), Complex<float>::Float(3.0f), Complex<float>::Float(4.0f), Complex<float>::Float(5.0f), Complex<float>::Float(6.0f)};
assert_parsed_expression_evaluate_to("[[1,2,3][4,5,6]]", a, 6);
assert_parsed_expression_evaluates_to("[[1,2,3][4,5,6]]", a, 2, 3);
Complex<double> b[6] = {Complex<double>::Float(1.0), Complex<double>::Float(2.0), Complex<double>::Float(3.0), Complex<double>::Float(4.0), Complex<double>::Float(5.0), Complex<double>::Float(6.0)};
assert_parsed_expression_evaluate_to("[[1,2,3][4,5,6]]", b, 6);
assert_parsed_expression_evaluates_to("[[1,2,3][4,5,6]]", b, 2, 3);
#endif
}

View File

@@ -9,29 +9,29 @@ using namespace Poincare;
QUIZ_CASE(poincare_parser) {
Complex<double> a[1] = {Complex<double>::Float(1.2*M_E)};
assert_parsed_expression_evaluate_to("1.2*X^(1)", a, 1);
assert_parsed_expression_evaluates_to("1.2*X^(1)", a);
Complex<float> b[1] = {Complex<float>::Float(std::pow((float)M_E, 2.0f)*M_E)};
assert_parsed_expression_evaluate_to("X^2*X^(1)", b, 1);
assert_parsed_expression_evaluates_to("X^2*X^(1)", b);
Complex<double> c[1] = {Complex<double>::Float(2.0*std::pow(3.0, 4.0)+2.0)};
assert_parsed_expression_evaluate_to("2*3^4+2", c, 1);
assert_parsed_expression_evaluates_to("2*3^4+2", c);
Complex<float> d[1] = {Complex<float>::Float(-2.0f*std::pow(3.0f, 4.0f)+2.0f)};
assert_parsed_expression_evaluate_to("-2*3^4+2", d,1);
assert_parsed_expression_evaluates_to("-2*3^4+2", d);
Complex<double> e[1] = {Complex<double>::Float(-std::sin(3.0)*2.0-3.0)};
assert_parsed_expression_evaluate_to("-sin(3)*2-3", e, 1, Radian);
assert_parsed_expression_evaluates_to("-sin(3)*2-3", e, Radian);
Complex<float> f[1] = {Complex<float>::Float(-0.003f)};
assert_parsed_expression_evaluate_to("-.003", f, 1);
assert_parsed_expression_evaluates_to("-.003", f);
Complex<double> g[1] = {Complex<double>::Float(2.0)};
assert_parsed_expression_evaluate_to(".02E2", g, 1);
assert_parsed_expression_evaluates_to(".02E2", g);
Complex<float> h[1] = {Complex<float>::Float(5.0f-2.0f/3.0f)};
assert_parsed_expression_evaluate_to("5-2/3", h, 1);
assert_parsed_expression_evaluates_to("5-2/3", h);
Complex<double> i[1] = {Complex<double>::Float(2.0/3.0-5.0)};
assert_parsed_expression_evaluate_to("2/3-5", i, 1);
assert_parsed_expression_evaluates_to("2/3-5", i);
Complex<float> j[1] = {Complex<float>::Float(-2.0f/3.0f-5.0f)};
assert_parsed_expression_evaluate_to("-2/3-5", j, 1);
assert_parsed_expression_evaluates_to("-2/3-5", j);
Complex<double> k[1] = {Complex<double>::Float(std::sin(3.0)*2.0*(4.0+2.0))};
assert_parsed_expression_evaluate_to("sin(3)2(4+2)", k, 1, Radian);
assert_parsed_expression_evaluates_to("sin(3)2(4+2)", k, Radian);
Complex<float> l[1] = {Complex<float>::Float(4.0f/2.0f*(2.0f+3.0f))};
assert_parsed_expression_evaluate_to("4/2*(2+3)", l, 1, Radian);
assert_parsed_expression_evaluates_to("4/2*(2+3)", l, Radian);
Complex<double> m[1] = {Complex<double>::Float(4.0/2.0*(2.0+3.0))};
assert_parsed_expression_evaluate_to("4/2*(2+3)", m, 1, Radian);
assert_parsed_expression_evaluates_to("4/2*(2+3)", m, Radian);
}

View File

@@ -8,16 +8,16 @@ using namespace Poincare;
QUIZ_CASE(poincare_power_evaluate) {
Complex<float> a[1] = {Complex<float>::Float(8.0f)};
assert_parsed_expression_evaluate_to("2^3", a, 1);
assert_parsed_expression_evaluates_to("2^3", a);
Complex<double> b[1] = {Complex<double>::Cartesian(28.0, 96.0)};
assert_parsed_expression_evaluate_to("(3+I)^4", b, 1);
assert_parsed_expression_evaluates_to("(3+I)^4", b);
Complex<float> c[1] = {Complex<float>::Cartesian(11.7412464f, 62.9137754f)};
assert_parsed_expression_evaluate_to("4^(3+I)", c, 1);
assert_parsed_expression_evaluates_to("4^(3+I)", c);
#if MATRICES_ARE_DEFINED
Complex<double> d[4] = {Complex<double>::Float(37.0), Complex<double>::Float(54.0), Complex<double>::Float(81.0), Complex<double>::Float(118.0)};
assert_parsed_expression_evaluate_to("[[1,2][3,4]]^3", d, 4);
assert_parsed_expression_evaluates_to("[[1,2][3,4]]^3", d, 2, 2);
#endif
}

View File

@@ -8,26 +8,26 @@ using namespace Poincare;
QUIZ_CASE(poincare_product_evaluate) {
Complex<float> a[1] = {Complex<float>::Float(2.0f)};
assert_parsed_expression_evaluate_to("1*2", a, 1);
assert_parsed_expression_evaluates_to("1*2", a);
Complex<double> b[1] = {Complex<double>::Cartesian(11.0, 7.0)};
assert_parsed_expression_evaluate_to("(3+I)*(4+I)", b, 1);
assert_parsed_expression_evaluates_to("(3+I)*(4+I)", b);
#if MATRICES_ARE_DEFINED
Complex<float> c[6] = {Complex<float>::Float(2.0f), Complex<float>::Float(4.0f), Complex<float>::Float(6.0f), Complex<float>::Float(8.0f), Complex<float>::Float(10.0f), Complex<float>::Float(12.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]*2", c, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]*2", c, 3, 2);
Complex<double> d[6] = {Complex<double>::Cartesian(3.0, 1.0), Complex<double>::Cartesian(5.0, 5.0), Complex<double>::Cartesian(9.0, 3.0), Complex<double>::Cartesian(12.0, 4.0), Complex<double>::Cartesian(15.0, 5.0), Complex<double>::Cartesian(18.0, 6.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]*(3+I)", d, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]*(3+I)", d, 3, 2);
assert_parsed_expression_evaluate_to("2*[[1,2][3,4][5,6]]", c, 6);
assert_parsed_expression_evaluates_to("2*[[1,2][3,4][5,6]]", c, 3, 2);
assert_parsed_expression_evaluate_to("(3+I)*[[1,2+I][3,4][5,6]]", d, 6);
assert_parsed_expression_evaluates_to("(3+I)*[[1,2+I][3,4][5,6]]", d, 3, 2);
Complex<float> e[12] = {Complex<float>::Float(11.0f), Complex<float>::Float(14.0f), Complex<float>::Float(17.0f), Complex<float>::Float(20.0f), Complex<float>::Float(23.0f), Complex<float>::Float(30.0f), Complex<float>::Float(37.0f), Complex<float>::Float(44.0f), Complex<float>::Float(35.0f), Complex<float>::Float(46.0f), Complex<float>::Float(57.0f), Complex<float>::Float(68.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]*[[1,2,3,4][5,6,7,8]]", e, 12);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]*[[1,2,3,4][5,6,7,8]]", e, 3, 4);
Complex<double> f[12] = {Complex<double>::Cartesian(11.0, 5.0), Complex<double>::Cartesian(13.0, 9.0), Complex<double>::Cartesian(17.0, 7.0), Complex<double>::Cartesian(20.0, 8.0), Complex<double>::Cartesian(23.0, 0.0), Complex<double>::Cartesian(30.0, 7.0), Complex<double>::Cartesian(37.0, 0.0), Complex<double>::Cartesian(44.0, 0.0), Complex<double>::Cartesian(35.0, 0.0), Complex<double>::Cartesian(46.0, 11.0), Complex<double>::Cartesian(57.0, 0.0), Complex<double>::Cartesian(68.0, 0.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]*[[1,2+I,3,4][5,6+I,7,8]]", f, 12);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]*[[1,2+I,3,4][5,6+I,7,8]]", f, 3, 4);
#endif
}

View File

@@ -8,28 +8,28 @@ using namespace Poincare;
QUIZ_CASE(poincare_substraction_evaluate) {
Complex<float> a[1] = {Complex<float>::Float(-1.0f)};
assert_parsed_expression_evaluate_to("1-2", a, 1);
assert_parsed_expression_evaluates_to("1-2", a);
Complex<double> b[1] = {Complex<double>::Cartesian(-1.0, 0.0)};
assert_parsed_expression_evaluate_to("3+I-(4+I)", b, 1);
assert_parsed_expression_evaluates_to("3+I-(4+I)", b);
#if MATRICES_ARE_DEFINED
Complex<float> c[6] = {Complex<float>::Float(-2.0f), Complex<float>::Float(-1.0f), Complex<float>::Float(0.0f), Complex<float>::Float(1.0f), Complex<float>::Float(2.0f), Complex<float>::Float(3.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]-3", c, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]-3", c, 3, 2);
Complex<double> d[6] = {Complex<double>::Cartesian(-3.0, -1.0), Complex<double>::Cartesian(-2.0, 0.0), Complex<double>::Cartesian(-1.0, -1.0), Complex<double>::Cartesian(0.0, -1.0), Complex<double>::Cartesian(1.0, -1.0), Complex<double>::Cartesian(2.0, -1.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]-(4+I)", d, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]-(4+I)", d, 3, 2);
Complex<float> e[6] = {Complex<float>::Float(2.0f), Complex<float>::Float(1.0f), Complex<float>::Float(0.0f), Complex<float>::Float(-1.0f), Complex<float>::Float(-2.0f), Complex<float>::Float(-3.0f)};
assert_parsed_expression_evaluate_to("3-[[1,2][3,4][5,6]]", e, 6);
assert_parsed_expression_evaluates_to("3-[[1,2][3,4][5,6]]", e, 3, 2);
Complex<double> f[6] = {Complex<double>::Cartesian(2.0, 1.0), Complex<double>::Cartesian(1.0, 0.0), Complex<double>::Cartesian(0.0, 1.0), Complex<double>::Cartesian(-1.0, 1.0), Complex<double>::Cartesian(-2.0, 1.0), Complex<double>::Cartesian(-3.0, 1.0)};
assert_parsed_expression_evaluate_to("3+I-[[1,2+I][3,4][5,6]]", f, 6);
assert_parsed_expression_evaluates_to("3+I-[[1,2+I][3,4][5,6]]", f, 3, 2);
Complex<float> g[6] = {Complex<float>::Float(-5.0f), Complex<float>::Float(-3.0f), Complex<float>::Float(-1.0f), Complex<float>::Float(1.0f), Complex<float>::Float(3.0f), Complex<float>::Float(5.0f)};
assert_parsed_expression_evaluate_to("[[1,2][3,4][5,6]]-[[6,5][4,3][2,1]]", g, 6);
assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]-[[6,5][4,3][2,1]]", g, 3, 2);
Complex<double> h[6] = {Complex<double>::Float(0.0), Complex<double>::Float(0.0), Complex<double>::Float(0.0), Complex<double>::Float(0.0), Complex<double>::Float(0.0), Complex<double>::Float(0.0)};
assert_parsed_expression_evaluate_to("[[1,2+I][3,4][5,6]]-[[1,2+I][3,4][5,6]]", h, 6);
assert_parsed_expression_evaluates_to("[[1,2+I][3,4][5,6]]-[[1,2+I][3,4][5,6]]", h, 3, 2);
#endif
}

View File

@@ -36,10 +36,10 @@ QUIZ_CASE(poincare_parse_symbol) {
QUIZ_CASE(poincare_symbol_approximate) {
Complex<double> a[1] = {Complex<double>::Float(M_PI)};
assert_parsed_expression_evaluate_to("P", a, 1);
assert_parsed_expression_evaluates_to("P", a);
Complex<float> b[1] = {Complex<float>::Float(M_E)};
assert_parsed_expression_evaluate_to("X", b, 1);
assert_parsed_expression_evaluates_to("X", b);
Complex<double> c[1] = {Complex<double>::Float(1200.0)};
assert_parsed_expression_evaluate_to("1.2E3", c, 1);
assert_parsed_expression_evaluates_to("1.2E3", c);
}

View File

@@ -95,27 +95,27 @@ QUIZ_CASE(poincare_parse_trigo) {
QUIZ_CASE(poincare_trigo_evaluate) {
Complex<double> a[1] = {Complex<double>::Float(-0.4161468365)};
assert_parsed_expression_evaluate_to("cos(2)", a, 1, Radian);
assert_parsed_expression_evaluates_to("cos(2)", a, Radian);
Complex<float> a1[1] = {Complex<float>::Cartesian(-1.0086248134f, -0.8893951958f)};
assert_parsed_expression_evaluate_to("cos(I-4)", a1, 1, Radian);
assert_parsed_expression_evaluates_to("cos(I-4)", a1, Radian);
Complex<double> b[1] = {Complex<double>::Float(0.9092974268)};
assert_parsed_expression_evaluate_to("sin(2)", b, 1, Radian);
assert_parsed_expression_evaluates_to("sin(2)", b, Radian);
Complex<float> b1[1] = {Complex<float>::Cartesian( 1.16780727488f, -0.768162763456f)};
assert_parsed_expression_evaluate_to("sin(I-4)", b1, 1, Radian);
assert_parsed_expression_evaluates_to("sin(I-4)", b1, Radian);
Complex<double> c[1] = {Complex<double>::Float(-2.18503986326151899)};
assert_parsed_expression_evaluate_to("tan(2)", c, 1, Radian);
assert_parsed_expression_evaluates_to("tan(2)", c, Radian);
Complex<float> c1[1] = {Complex<float>::Cartesian(-0.27355308280730f, 1.002810507583504f)};
assert_parsed_expression_evaluate_to("tan(I-4)", c1, 1, Radian);
assert_parsed_expression_evaluates_to("tan(I-4)", c1, Radian);
Complex<double> a2[1] = {Complex<double>::Float(3.762195691)};
assert_parsed_expression_evaluate_to("cosh(2)", a2, 1, Radian);
assert_parsed_expression_evaluates_to("cosh(2)", a2, Radian);
Complex<float> a3[1] = {Complex<float>::Cartesian(14.754701170483756280f,-22.96367349919304059f)};
assert_parsed_expression_evaluate_to("cosh(I-4)", a3, 1, Radian);
assert_parsed_expression_evaluates_to("cosh(I-4)", a3, Radian);
Complex<double> b2[1] = {Complex<double>::Float(3.62686040784701876)};
assert_parsed_expression_evaluate_to("sinh(2)", b2, 1, Radian);
assert_parsed_expression_evaluates_to("sinh(2)", b2, Radian);
Complex<float> b3[1] = {Complex<float>::Cartesian(-14.744805188558725031023f, 22.979085577886129555168f)};
assert_parsed_expression_evaluate_to("sinh(I-4)", b3, 1, Radian);
assert_parsed_expression_evaluates_to("sinh(I-4)", b3, Radian);
Complex<double> c2[1] = {Complex<double>::Float(0.9640275800758168839464)};
assert_parsed_expression_evaluate_to("tanh(2)", c2, 1, Radian);
assert_parsed_expression_evaluates_to("tanh(2)", c2, Radian);
Complex<float> c3[1] = {Complex<float>::Cartesian(-1.00027905623446556836909f, 0.000610240921376259f)};
assert_parsed_expression_evaluate_to("tanh(I-4)", c3, 1, Radian);
assert_parsed_expression_evaluates_to("tanh(I-4)", c3, Radian);
}