A powerful Java library for parsing, simplifying, and analyzing mathematical expressions with automatic function type identification.
- Expression Parsing: Convert string expressions to abstract syntax trees
- Automatic Simplification: Reduce expressions to their simplest form
- Function Identification: Automatically detect and classify function types
- Comprehensive Analysis: Get detailed mathematical properties for each function type
- Type-Safe API: Strongly typed function classes with specific methods
- Extensible Design: Easy to add new function types and operations
Add the GitHub Packages repository to your build file:
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/sudojed/reductio</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.sudojed</groupId>
<artifactId>reductio</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>Note: You'll need to authenticate with GitHub Packages. Add to your ~/.m2/settings.xml:
<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>YOUR_GITHUB_TOKEN</password>
</server>
</servers>repositories {
maven {
url = uri("https://maven.pkg.github.com/sudojed/reductio")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN")
}
}
}
dependencies {
implementation 'com.github.sudojed:reductio:1.1.0'
}Add the JitPack repository to your build file:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.sudojed</groupId>
<artifactId>reductio</artifactId>
<version>v1.1.0</version>
</dependency>
</dependencies>repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.sudojed:reductio:v1.1.0'
}resolvers += "jitpack" at "https://jitpack.io"
libraryDependencies += "com.github.sudojed" % "reductio" % "v1.1.0":repositories [["jitpack" "https://jitpack.io"]]
:dependencies [[com.github.sudojed/reductio "v1.1.0"]]To use GitHub Packages, you'll need a Personal Access Token:
- Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
- Generate a new token with
read:packagesscope - Set environment variables:
export GITHUB_USERNAME=your-username export GITHUB_TOKEN=your-token
- Or add to your Maven
settings.xmlor Gradlegradle.properties
# Create a token at: https://github.com/settings/tokens
# Select scope: read:packages
export GITHUB_USERNAME=your-username
export GITHUB_TOKEN=ghp_your_token_here<!-- Add to pom.xml -->
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/sudojed/reductio</url>
</repository>
</repositories><!-- Add to ~/.m2/settings.xml -->
<servers>
<server>
<id>github</id>
<username>${env.GITHUB_USERNAME}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
</servers><dependency>
<groupId>com.github.sudojed</groupId>
<artifactId>reductio</artifactId>
<version>1.1.0</version>
</dependency>import com.reductio.Parser;
import com.reductio.Expr;
// Parse and simplify expressions
Expr expr = Parser.parse("x^2 - 4x + 3");
Expr simplified = expr.simplify();
System.out.println(simplified.show());- Clone the repository:
git clone https://github.com/sudojed/reductio.git- Build from source:
cd reductio
mvn clean installimport com.reductio.Parser;
import com.reductio.Expr;
import com.reductio.funcoes.Function;
import com.reductio.funcoes.polinomial.Quadrada;
// Parse a mathematical expression
Expr expr = Parser.parse("x^2 - 4x + 3");
// Simplify the expression
Expr simplified = expr.simplify();
// Automatically identify the function type
Function function = Function.identify(simplified, "x");
if (function instanceof Quadrada) {
Quadrada quadratic = (Quadrada) function;
// Get mathematical properties
System.out.println("Type: " + quadratic.getType());
System.out.println("Discriminant: " + quadratic.getDiscriminante());
System.out.println("Vertex: " + Arrays.toString(quadratic.getVertice()));
System.out.println("Roots: " + Arrays.toString(quadratic.encontrarRaizes()));
// Evaluate at specific points
System.out.println("f(2) = " + quadratic.evaluate(2.0));
}| Type | Pattern | Example | Features |
|---|---|---|---|
| Linear | ax + b |
2x + 3 |
Slope, intercepts, monotonicity |
| Quadratic | ax² + bx + c |
x^2 - 4x + 3 |
Vertex, discriminant, roots, concavity |
| Cubic | ax³ + bx² + cx + d |
x^3 - 2x^2 + x + 1 |
Critical points, inflection points |
| Polynomial | aₙxⁿ + ... + a₁x + a₀ |
5x^4 - 3x^3 + 2x^2 |
General polynomial analysis |
| Pattern | Example | Features |
|---|---|---|
a * b^(cx + d) + e |
2^x, e^(2x+1) |
Base, growth rate, asymptotes |
| Pattern | Example | Features |
|---|---|---|
a * log_b(cx + d) + e |
ln(x), log(2x+1) |
Base, domain restrictions, asymptotes |
| Pattern | Example | Features |
|---|---|---|
a * trig(bx + c) + d |
sin(x), 2*cos(3x+1) |
Period, amplitude, phase shift |
// Parse expression from string
Expr expr = Parser.parse("2x + 3");
// Validate expression
boolean isValid = Parser.isValid("invalid expression");
// Get supported functions
Set<String> functions = Parser.getSupportedFunctions();// Simplify expression
Expr simplified = expr.simplify();
// Get string representation
String str = expr.show();
// Evaluate with variables
Map<String, Double> vars = Map.of("x", 2.0);
double result = expr.evaluate(vars);// Automatic identification
Function func = Function.identify(expr, "x");
// Common properties
String type = func.getType();
String domain = func.getDomain();
String range = func.getRange();
double value = func.evaluate(2.0);Linear linear = new Linear("2x + 3", "x");
// Properties
double slope = linear.getCoeficienteAngular();
double intercept = linear.getCoeficienteLinear();
boolean increasing = linear.isCrescente();
double root = linear.encontrarRaiz();Quadrada quadratic = new Quadrada("x^2 - 4x + 3", "x");
// Properties
double discriminant = quadratic.getDiscriminante();
double[] vertex = quadratic.getVertice();
double[] roots = quadratic.encontrarRaizes();
boolean concaveUp = quadratic.isConcavidadeParaCima();Exponencial exponential = new Exponencial("2^x", "x");
// Properties
double base = exponential.getBase();
boolean increasing = exponential.isCrescente();
double asymptote = exponential.getAssintotaHorizontal();Logaritmica logarithmic = new Logaritmica("ln(x)", "x");
// Properties
double base = logarithmic.getBase();
boolean isNatural = logarithmic.isLogaritmoNatural();
double asymptote = logarithmic.getAssintotaVertical();Trigonometrica trig = new Trigonometrica("sin(x)", "x");
// Properties
double period = trig.getPeriodo();
double amplitude = trig.getAmplitude();
double frequency = trig.getFrequencia();
boolean isOdd = trig.isFuncaoImpar();// Simple arithmetic
Expr expr1 = Parser.parse("2 + 3 * 4");
System.out.println(expr1.simplify().show()); // "14"
// With variables
Expr expr2 = Parser.parse("2x + 3y - 5x");
System.out.println(expr2.simplify().show()); // "-3x + 3y"
// Functions
Expr expr3 = Parser.parse("sin(x) + cos(x)");
Map<String, Double> vars = Map.of("x", Math.PI/4);
System.out.println(expr3.evaluate(vars)); // ~1.414// Quadratic analysis
Function quad = Function.identify(Parser.parse("x^2 - 6x + 8"), "x");
if (quad instanceof Quadrada) {
Quadrada q = (Quadrada) quad;
System.out.println("Complete analysis:");
System.out.println(q.getAnaliseCompleta());
}
// Trigonometric analysis
Function trig = Function.identify(Parser.parse("2*sin(3x + 1)"), "x");
if (trig instanceof Trigonometrica) {
Trigonometrica t = (Trigonometrica) trig;
System.out.println("Period: " + t.getPeriodo());
System.out.println("Amplitude: " + t.getAmplitude());
System.out.println("Phase shift: " + t.getDeslocamentoFase());
}// Step-by-step simplification
Map<Integer, String> steps = new LinkedHashMap<>();
int[] counter = {0};
Expr expr = Parser.parse("(x + 2)^2 - (x + 2)");
Expr result = expr.simplify(steps, counter);
steps.forEach((step, expression) ->
System.out.println("Step " + step + ": " + expression));Expr (abstract)
├── Constant
├── Variable
├── BinaryOp
└── FunctionExpr
Function (abstract)
├── Polinomial
│ ├── Linear
│ ├── Quadrada
│ └── Cubica
├── Exponencial
├── Logaritmica
└── Trigonometrica
- Strategy Pattern: Different simplification strategies for expression types
- Factory Pattern: Automatic function type identification and instantiation
- Visitor Pattern: Expression tree traversal and analysis
- Builder Pattern: Complex expression construction
- Parsing: O(n) time complexity for expression length
- Simplification: O(n log n) for most expressions
- Evaluation: O(1) for constants, O(n) for complex expressions
- Memory: Minimal overhead with immutable expression trees
Run the test suite:
mvn testExample test execution:
// Comprehensive testing
@Test
public void testFunctionIdentification() {
assertEquals(Linear.class,
Function.identify(Parser.parse("2x + 3"), "x").getClass());
assertEquals(Quadrada.class,
Function.identify(Parser.parse("x^2 - 1"), "x").getClass());
assertEquals(Exponencial.class,
Function.identify(Parser.parse("2^x"), "x").getClass());
}We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Ensure all tests pass:
mvn test - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow Java naming conventions
- Add JavaDoc for public APIs
- Include unit tests for new features
- Maintain backward compatibility
This project is licensed under the MIT License - see the LICENSE file for details.
- Documentation: Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: abnerjaredejede@gmail.com
- Inspired by mathematical libraries like SymPy and Mathematica
- Built with modern Java practices and design patterns
- Community feedback and contributions