mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-28 18:20:14 +01:00
[poincare] Implement getVariables on Expression
This commit is contained in:
@@ -21,7 +21,7 @@ private:
|
||||
return emptyModel();
|
||||
}
|
||||
void setModelAtIndex(Shared::ExpressionModel * f, int i) override;
|
||||
static constexpr int k_maxNumberOfEquations = 6;
|
||||
static constexpr int k_maxNumberOfEquations = Poincare::Expression::k_maxNumberOfVariables; // Enable the same number of equations as the number of unknown variables
|
||||
Equation m_equations[k_maxNumberOfEquations];;
|
||||
};
|
||||
|
||||
|
||||
@@ -215,6 +215,17 @@ public:
|
||||
* - (-1) if the expression is not a polynome
|
||||
* - the degree of the polynome otherwise */
|
||||
virtual int polynomialDegree(char symbolName) const;
|
||||
/* getVariables fills the table variables with the variable present in the
|
||||
* expression and returns the number of entries in filled in variables.
|
||||
* For instance getVariables('x+y+2*w/cos(4)') would result in
|
||||
* variables = ['x', 'y', 'w'] and would return 3. If the final number of
|
||||
* variables would overflow the maxNumberOfVariables, getVariables return -1 */
|
||||
static constexpr int k_maxNumberOfVariables = 6;
|
||||
virtual int getVariables(char * variables) const;
|
||||
/* getPolynomialCoefficients fill the table coefficients with the expressions
|
||||
* of the first 4 polynomial coefficients. coefficients is null-terminated
|
||||
* and has up to 4 entries. */
|
||||
//virtual void getPolynomialCoefficients(char symbolName, Expression ** coefficients) const;
|
||||
|
||||
/* Comparison */
|
||||
/* isIdenticalTo is the "easy" equality, it returns true if both trees have
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
Type type() const override;
|
||||
Expression * clone() const override;
|
||||
int polynomialDegree(char symbolName) const override;
|
||||
int getVariables(char * variables) const override;
|
||||
Sign sign() const override;
|
||||
bool isMatrixSymbol() const;
|
||||
bool isScalarSymbol() const;
|
||||
|
||||
@@ -207,6 +207,18 @@ int Expression::polynomialDegree(char symbolName) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Expression::getVariables(char * variables) const {
|
||||
int numberOfVariables = 0;
|
||||
for (int i = 0; i < numberOfOperands(); i++) {
|
||||
int n = operand(i)->getVariables(variables);
|
||||
if (n < 0) {
|
||||
return -1;
|
||||
}
|
||||
numberOfVariables = n > numberOfVariables ? n : numberOfVariables;
|
||||
}
|
||||
return numberOfVariables;
|
||||
}
|
||||
|
||||
bool Expression::isOfType(Type * types, int length) const {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (type() == types[i]) {
|
||||
|
||||
@@ -113,6 +113,26 @@ int Symbol::polynomialDegree(char symbol) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Symbol::getVariables(char * variables) const {
|
||||
size_t variablesLength = strlen(variables);
|
||||
if (m_name >= 'a' && m_name <= 'z') {
|
||||
char * currentChar = variables;
|
||||
while (*currentChar != 0) {
|
||||
if (*currentChar == m_name) {
|
||||
return variablesLength;
|
||||
}
|
||||
currentChar++;
|
||||
}
|
||||
if (variablesLength < k_maxNumberOfVariables) {
|
||||
variables[variablesLength] = m_name;
|
||||
variables[variablesLength+1] = 0;
|
||||
return variablesLength+1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return variablesLength;
|
||||
}
|
||||
|
||||
Expression * Symbol::replaceSymbolWithExpression(char symbol, Expression * expression) {
|
||||
if (m_name == symbol) {
|
||||
Expression * value = expression->clone();
|
||||
|
||||
@@ -77,3 +77,28 @@ QUIZ_CASE(poincare_characteristic_range) {
|
||||
assert_parsed_expression_has_characteristic_range("log(cos(40*x))", 9.0f);
|
||||
assert_parsed_expression_has_characteristic_range("cos(cos(x))", 360.0f);
|
||||
}
|
||||
|
||||
void assert_parsed_expression_has_variables(const char * expression, const char * variables) {
|
||||
Expression * e = parse_expression(expression);
|
||||
char variableBuffer[Expression::k_maxNumberOfVariables+1] = {0};
|
||||
int numberOfVariables = e->getVariables(variableBuffer);
|
||||
if (variables == nullptr) {
|
||||
assert(numberOfVariables == -1);
|
||||
} else {
|
||||
assert(numberOfVariables == strlen(variables));
|
||||
char * currentChar = variableBuffer;
|
||||
while (*variables != 0) {
|
||||
assert(*currentChar++ == *variables++);
|
||||
}
|
||||
}
|
||||
delete e;
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_get_variables) {
|
||||
assert_parsed_expression_has_variables("x+y", "xy");
|
||||
assert_parsed_expression_has_variables("x+y+z+2*t", "xyzt");
|
||||
assert_parsed_expression_has_variables("abcdef", "abcdef");
|
||||
assert_parsed_expression_has_variables("abcdefg", nullptr);
|
||||
assert_parsed_expression_has_variables("abcde", "abcde");
|
||||
assert_parsed_expression_has_variables("x^2+2*y+k!*A+w", "xykw");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user