mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Create Expression::reduceChildren and assert that deepReduce
is not called on a Matrix
This commit is contained in:
committed by
LeaNumworks
parent
dcf88eae01
commit
78ccb69b59
@@ -159,6 +159,7 @@ public:
|
||||
static Expression ParseAndSimplify(const char * text, Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression simplify(Context & context, Preferences::AngleUnit angleUnit);
|
||||
Expression deepReduce(Context & context, Preferences::AngleUnit angleUnit);
|
||||
void reduceChildren(Context & context, Preferences::AngleUnit angleUnit);
|
||||
|
||||
/* Approximation Helper */
|
||||
template<typename U> static U epsilon();
|
||||
|
||||
@@ -82,8 +82,8 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Ang
|
||||
matrix.addChildAtIndexInPlace(Addition(r0, sqr), 1, 1);
|
||||
matrix.setDimensions(1, 2);
|
||||
replaceWithInPlace(matrix);
|
||||
Expression result = matrix.deepReduce(context, angleUnit);
|
||||
return result;
|
||||
matrix.reduceChildren(context, angleUnit);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ bool Expression::DependsOnVariables(const Expression e, Context & context) {
|
||||
}
|
||||
|
||||
bool Expression::getLinearCoefficients(char * variables, Expression coefficients[], Expression constant[], Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
assert(!recursivelyMatches(IsMatrix, context));
|
||||
char * x = variables;
|
||||
while (*x != 0) {
|
||||
int degree = polynomialDegree(*x);
|
||||
@@ -271,14 +272,15 @@ Expression Expression::simplify(Context & context, Preferences::AngleUnit angleU
|
||||
}
|
||||
|
||||
Expression Expression::deepReduce(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
/* assert(!recursivelyMatches(IsMatrix, context));
|
||||
* We could assert that no matrix is involved but we sometimes call deepReduce
|
||||
* with a matrix at root to avoid calling deepReduce on all matrix children.
|
||||
* (Matrix::rowCanonize for instance) */
|
||||
assert(!IsMatrix(*this, context));
|
||||
reduceChildren(context, angleUnit);
|
||||
return shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
void Expression::reduceChildren(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
for (int i = 0; i < numberOfChildren(); i++) {
|
||||
childAtIndex(i).deepReduce(context, angleUnit);
|
||||
}
|
||||
return shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
Expression Expression::deepBeautify(Context & context, Preferences::AngleUnit angleUnit) {
|
||||
|
||||
@@ -160,16 +160,11 @@ int Matrix::ArrayInverse(T * array, int numberOfRows, int numberOfColumns) {
|
||||
}
|
||||
|
||||
Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit, Multiplication determinant) {
|
||||
// The matrix has to be reduced to be able to spot 0 inside it
|
||||
Expression reduced = deepReduce(context, angleUnit);
|
||||
// The MatrixNode should change only if one of the child is Undefined
|
||||
if (reduced.type() != ExpressionNode::Type::Matrix) {
|
||||
return Matrix();
|
||||
}
|
||||
Matrix matrix = static_cast<Matrix &>(reduced);
|
||||
// The matrix children have to be reduced to be able to spot 0
|
||||
reduceChildren(context, angleUnit);
|
||||
|
||||
int m = matrix.numberOfRows();
|
||||
int n = matrix.numberOfColumns();
|
||||
int m = numberOfRows();
|
||||
int n = numberOfColumns();
|
||||
|
||||
int h = 0; // row pivot
|
||||
int k = 0; // column pivot
|
||||
@@ -177,7 +172,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit,
|
||||
while (h < m && k < n) {
|
||||
// Find the first non-null pivot
|
||||
int iPivot = h;
|
||||
while (iPivot < m && matrix.matrixChild(iPivot, k).isRationalZero()) {
|
||||
while (iPivot < m && matrixChild(iPivot, k).isRationalZero()) {
|
||||
iPivot++;
|
||||
}
|
||||
if (iPivot == m) {
|
||||
@@ -189,7 +184,7 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit,
|
||||
// Swap row h and iPivot
|
||||
if (iPivot != h) {
|
||||
for (int col = h; col < n; col++) {
|
||||
matrix.swapChildrenInPlace(iPivot*n+col, h*n+col);
|
||||
swapChildrenInPlace(iPivot*n+col, h*n+col);
|
||||
}
|
||||
// Update determinant: det *= -1
|
||||
if (!determinant.isUninitialized()) { determinant.addChildAtIndexInPlace(Rational(-1), 0, determinant.numberOfChildren()); }
|
||||
@@ -201,10 +196,10 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit,
|
||||
for (int j = k+1; j < n; j++) {
|
||||
Expression opHJ = matrixChild(h, j);
|
||||
Expression newOpHJ = Division(opHJ, divisor.clone());
|
||||
matrix.replaceChildAtIndexInPlace(h*n+j, newOpHJ);
|
||||
replaceChildAtIndexInPlace(h*n+j, newOpHJ);
|
||||
newOpHJ = newOpHJ.shallowReduce(context, angleUnit);
|
||||
}
|
||||
matrix.replaceChildInPlace(divisor, Rational(1));
|
||||
replaceChildInPlace(divisor, Rational(1));
|
||||
|
||||
/* Set to 0 all M[i][j] i != h, j > k by linear combination */
|
||||
for (int i = 0; i < m; i++) {
|
||||
@@ -213,17 +208,17 @@ Matrix Matrix::rowCanonize(Context & context, Preferences::AngleUnit angleUnit,
|
||||
for (int j = k+1; j < n; j++) {
|
||||
Expression opIJ = matrixChild(i, j);
|
||||
Expression newOpIJ = Subtraction(opIJ, Multiplication(matrixChild(h, j).clone(), factor.clone()));
|
||||
matrix.replaceChildAtIndexInPlace(i*n+j, newOpIJ);
|
||||
replaceChildAtIndexInPlace(i*n+j, newOpIJ);
|
||||
newOpIJ.childAtIndex(1).shallowReduce(context, angleUnit);
|
||||
newOpIJ = newOpIJ.shallowReduce(context, angleUnit);
|
||||
}
|
||||
matrix.replaceChildAtIndexInPlace(i*n+k, Rational(0));
|
||||
replaceChildAtIndexInPlace(i*n+k, Rational(0));
|
||||
}
|
||||
h++;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -93,7 +93,8 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Ang
|
||||
matrix.addChildAtIndexInPlace(Addition(r0.clone(), m), 1, 1);
|
||||
matrix.setDimensions(1, 2);
|
||||
replaceWithInPlace(matrix);
|
||||
return matrix.deepReduce(context, angleUnit);
|
||||
matrix.reduceChildren(context, angleUnit);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user