#include #include #include #include #include #include extern "C" { #include } #include namespace Poincare { Expression::Type ConfidenceInterval::type() const { return Type::ConfidenceInterval; } Expression * ConfidenceInterval::clone() const { ConfidenceInterval * a = new ConfidenceInterval(m_operands, true); return a; } int ConfidenceInterval::polynomialDegree(char symbolName) const { return -1; } Expression * ConfidenceInterval::shallowReduce(Context& context, AngleUnit angleUnit) { Expression * e = Expression::shallowReduce(context, angleUnit); if (e != this) { return e; } Expression * op0 = editableOperand(0); Expression * op1 = editableOperand(1); #if MATRIX_EXACT_REDUCING if (op0->type() == Type::Matrix || op1->type() == Type::Matrix) { return replaceWith(new Undefined(), true); } #endif if (op0->type() == Type::Rational) { Rational * r0 = static_cast(op0); if (r0->numerator().isNegative() || Integer::NaturalOrder(r0->numerator(), r0->denominator()) > 0) { return replaceWith(new Undefined(), true); } } if (op1->type() == Type::Rational) { Rational * r1 = static_cast(op1); if (!r1->denominator().isOne() || r1->numerator().isNegative()) { return replaceWith(new Undefined(), true); } } if (op0->type() != Type::Rational || op1->type() != Type::Rational) { return this; } Rational * r0 = static_cast(op0); Rational * r1 = static_cast(op1); detachOperands(); // Compute [r0-1/sqr(r1), r0+1/sqr(r1)] Expression * sqr = new Power(r1, new Rational(-1, 2), false); const Expression * newOperands[2] = {new Addition(r0, new Multiplication(new Rational(-1), sqr, false), false), new Addition(r0, sqr, true)}; Expression * matrix = replaceWith(new Matrix(newOperands, 1, 2, false), true); return matrix->deepReduce(context, angleUnit); } template Evaluation * ConfidenceInterval::templatedApproximate(Context& context, AngleUnit angleUnit) const { Evaluation * fInput = operand(0)->privateApproximate(T(), context, angleUnit); Evaluation * nInput = operand(1)->privateApproximate(T(), context, angleUnit); T f = static_cast *>(fInput)->toScalar(); T n = static_cast *>(nInput)->toScalar(); delete fInput; delete nInput; if (std::isnan(f) || std::isnan(n) || n != (int)n || n < 0 || f < 0 || f > 1) { return new Complex(Complex::Undefined()); } std::complex operands[2]; operands[0] = std::complex(f - 1/std::sqrt(n)); operands[1] = std::complex(f + 1/std::sqrt(n)); return new MatrixComplex(operands, 1, 2); } }