Representing Math Equations as Java Objects - java

I am trying to design a way to represent mathematical equations as Java Objects. This is what I've come up with so far:
Term
-Includes fields such as coefficient (which could be negative), exponent and variable (x, y, z, etc). Some fields may even qualify as their own terms alltogether, introducing recursion.
-Objects that extend Term would include things such as TrigTerm to represent trigonometric functions.
Equation
-This is a collection of Terms
-The toString() method of Equation would call the toString() method of all of its Terms and concatenate the results.
The overall idea is that I would be able to programmatically manipulate the equations (for example, a dirivative method that would return an equation that is the derivative of the equation it was called for, or an evaluate method that would evaluate an equation for a certain variable equaling a certain value).
What I have works fine for simple equations:
This is just two Terms: one with a variable "x" and an exponent "2" and another which is just a constant "3."
But not so much for more complex equations:
Yes, this is a terrible example but I'm just making a point.
So now for the question: what would be the best way to represent math equations as Java objects? Are there any libraries that already do this?

what would be the best way to
represent math equations as Java
objects?
I want you to notice, you don't have any equations. Equations look like this;
x = 3
What you have are expressions: collections of symbols that could, under some circumstances, evaluate out to some particular values.
You should write a class Expression. Expression has three subclasses: Constant (e.g. 3), Variable (e.g. x), and Operation.
An Operation has a type (e.g. "exponentiation" or "negation") and a list of Expressions to work on. That's the key idea: an Operation, which is an Expression, also has some number of Expressions.
So your is SUM(EXP(X, 2), 3) -- that is, the SUM Operation, taking two expressions, the first being the Exponentiation of the Expressions Variable X and Constant 2, and the second being the Constant 3.
This concept can be infinitely elaborated to represent any expression you can write on paper.
The hard part is evaluating a string that represents your expression and producing an Expression object -- as someone suggested, read some papers about parsing. It's the hardest part but still pretty easy.
Evaluating an Expression (given fixed values for all your Variables) and printing one out are actually quite easy. More complicated transforms (like differentiation and integration) can be challenging but are still not rocket science.

Consult a good compiler book for details about how to write the part of a compiler that converts input into an expression tree.
You might find this series inspirational: http://compilers.iecc.com/crenshaw/
If you "just" want to evaluate an input string, then have a look at the snippet compiler in the Javassist library.

Here I described the representation of parsed math expressions as Abstract Syntax Trees in the Symja project.
The D[f,x] function in the D.java file implements a derivative function by reading the initial Derivative[] rules from the System.mep file.

Related

XGBoost Cross Validation with different cut point

I would like to create two models of binary prediction: one with the cut point strictly greater than 0.5 (in order to obtain fewer signals but better ones) and second with the cut point strictly less than 0.5.
Doing the cross-validation, we have a test error related to the cut point equal to 0.5. How can I do it with other cut value? I talk about XGBoost for Java.
xgboost returns a list of scores. You can do what ever you want to that list of scores.
I think that particularly in Java, it returns a 2d ArrayList of shape (1, n)
In binary prediction you probably used a logistic function, thus your scores will be between 0 to 1.
Take your scores object and create a custom function that will calculate new predictions, by the rules you've described.
If you are using an automated/xgboost-implemented Cross Validation Function, you might want to build a customized evaluation function which will do as you bid, and pass it as an argument to xgb.cv
If you want to be smart when setting your threshold, I suggest reading about AUC of Roc Curve and Precision Recall Curve.

The user input for a calculating the tangent of a graph

I am making a program that calculates the equation for the tangent of a graph at a given point and ideally I'd want it to work for any type of graph. e.g. 1/x ,x^2 ,ln(x), e^x, sin, tan. I know how to work out the tangent and everything but I just don't really know how to get the input from the user.
Would I have to have options where they choose the type of graph and then fill in the coefficients for it e.g. "Choice 1: 1/(Ax^B) Enter the values of A and B"? Or is there a way so that the program recognises what the user types in so that instead of entering a choice and then the values of A and B, the user can type "1/3x^2" and the program would recognise that the A and B are 3 and 2 and that the graph is a 1/x graph.
This website is kind of an example of what I would like to do be able to do: https://www.symbolab.com/solver/tangent-line-calculator
Thanks for any help :)
Looks like you want to evalute the expression. In that case, you could look into Dijkstra's Shunting-Yard algorithm to convert the expression to prefix notation, and then evaluate the expression using stacks. Alternatively, you can use a library such as exp4j. There are multiple tutorials for it, but remember that you need to add operations for both binary and unary operations (binary meaning it supports 2 operations while unary is like sin(x)).
Then, after you evaluate the expression, you can use first principles to solve. I have an example of this system working without exp4j on my github repository. If you go back in the commit history, you can see the implementation with exp4j as well.
Parsing a formula from user input is itself a problem much harder than calculating the tangent. If this is an assignment, see if the wording allows for the choice of the functions and its parameters, as you're suggesting, because otherwise you are going to spend 10% of time writing code for calculating the derivative and 90% for reading the function from the standard input.
If it's your own idea and you'd like to try your hand at it, a teaser is that you will likely need to design a whole class structure for different operators, constants, and the unknown. Keep a stack of mathematical operations, because in 1+2*(x+1)+3 the multiplication needs to happen before the outer additions, but after the inner one. You'll have to deal with reading non-uniform input that has a high level of freedom (in whitespace, omission of * sign, implicit zero before a –, etc.) Regular expressions may be of help, but be prepared for a debugging nightmare and a ton of special cases anyway.
If you're fine with restricting your users (yourself?) to valid expressions following JavaScript syntax (which your examples are not, due to the implied multiplication and the haphazard rules of precedence thereof to the 1/...) and you can trust them absolutely in having no malicious intentions, see this question. You wouldn't have your expression represented as a formula internally, but you would still be able to evaluate it in different points x. Then you can approximate the derivative by (f(x+ε) - f(x)) / ε with some sufficiently small ε (but not too small either, using trial and error for convergence). Watch out for points where the function has a jump, but in basic principle this works, too.

Algorithm or Function to return Y values for X and Equation Inputs

I am creating a graphing calculator and I need an algorithm to interpret equations that users input. For example, if the user types in "x^3+5x^2-4x-9", the algorithm should take the string input and return (0, -9), (1, -7) and so on. How should I go about doing this? Are there any open source libraries I can use? Thanks in advance.
You could implement a Shunting-Yard Algorithm, but there are plenty of mathematical parsers already out there. There is a very famous saying in software development:
"Don't reinvent the wheel."
I encountered this problem when developing my own app. If there's already open source libraries out there, you should definitely use them to your advantage. That being said, I would recommend the MathEval library if you want double precision. Double is usually enough in terms of precision, because precision after double such as BigDecimal, which is an exact way of representing numbers is extremely expensive in terms of speed and memory, two things you want to reduce in computation.
The easiest, O(n) method in which you would generate solutions is set a range in a for loop, and use MathEval's setVariable method for x based on the iterations in the loop and retrieve the result through MathEval's evaluate method. There could be some boundaries in the equation, so make sure you compute the necessary restrictions and condition them inside your loop.
Check out this link Terrance which mentions the MathEval library:
Built-in method for evaluating math expressions in Java
Let me know if you need any help because I have implemented both the algorithm from scratch and through an external library.

How to implement equivalence class in Java?

What would be the simple way to implement equivalence class in Java? Is there any library for that purpose?
The bothering part is how to write an efficient and non-naive "equal" operator.
Let S = {x,y,z,w,h}. If we use a mapping x->1, y->1, z->1, w->2, h->2 for the equivalence class of S, one has to consider the mapping x->10, y->10, z->10, w->20, h->20 as the same equivalence class.
Naive "equal" operator can quickly become time-consuming when the cardinal of the set S becomes large.
What would be the simple way? Any idea?
[EDITED] To clarify, the specific problem can be formalized as follows:
Let S be a non-empty set. We denote by M a set of partial mappings from V to integers. It is relatively easy to show that the binary relation \sim defined below derives an equivalence relation on M.
For m1 and m2 two partial mappings of M, m1 \sim m2 if and only if,
for any a of V, m1(a) is defined if and only if m2(a) is defined
for any a,b of V, m1(a) and m1(b) are both defined to be the same
integer value 'z1' if and only if m2(a) and m2(b) are both defined
to the same integer value 'z2' (which may or may not differ from
'z1')
Example.
a->9,b->9,w->1 \sim a->10,b->10,w->0
But it is not correct to say
a->5 \sim b->9
Thanks.
From what I understand from your question you can find the greatest common divisor (Euclid's algorithm recursively) for a set once and map the quotients with that instead - if they're exactly equal with another set it's equal, else not. This will only work if the sets are equal in size and mappings.
If I understand you correct, you could apply vector normalization. A 3d vector for example is normalized to a length of 1 by dividing all of its components separately with the vectors length. If two normalized vector's components are equal, their original (non-normalized) vectors point in the same direction (which is what I think you define as 'equal')
x,y,z,w,h would in your case be a 5-dimensional vector. They belong to the same class when the show into the same direction, but may have an arbitrary length.
Aside: I assume that the set S is actually the set V in your definition.
I think Uli is on the right track, although I would not assume that Set(Set(E)).equals() is efficient for your purposes. (Sorry, I couldn't get the lt or gt symbols to come through)
The default implementation of Set(E).equals() is likely O(nlog n) or O(n^2). Set(E).equals() almost certainly involves sorting; O(nlog n) is as good as it gets. I suggest you look at radix sort. It's O(n*log n), but grows very slowly.

Static Typing and Writing a Simple Matrix Library

Aye it's been done a million times before, but damnit I want to do it again. I'm writing a simple Matrix Library for C++ with the intention of doing it right. I've come across something that's fairly obvious in mathematics, but not so obvious to a strongly typed system -- the fact that a 1x1 matrix is just a number. To avoid this, I started walking down the hairy path of matrices as a composition of vectors, but also stumbled upon the fact that two vectors multiplied together could either be a number or a dyad, depending on the orientation of the two.
My question is, what is the right way to deal with this situation in a strongly typed language like C++ or Java?
something that's fairly obvious in
mathematics, but not so obvious to a
strongly typed system -- the fact that
a 1x1 matrix is just a number.
That's arguable. A hardcore mathematician (I'm not) would probably argue against it, he would say that a 1x1 matrix can be regarded as isomorphic (or something like that) to a scalar, but they are conceptually different things. Only in some informal sense "a 1x1 matrix is a scalar" (similar, though stronger, that a complex number without an imaginary part "is a real").
I don't think that that correspondence should be reflected in a strong typed language. And I dont' think it is, in typical implementations (of complex or matrix), eg. Java Apache Commons Math. For example, a Complex with zero imaginary part is not a Number (from the type POV - they cannot be casted one into another).
In the case of matrices, the correspondence is even more disputable. Should we be able to multiply two matrices of sizes (4x3) x (1x1) ? If we regard the second as a scalar, it's valid, but not as a matrix, since it violates the restriction on matrix dimensions for multiplication. And I believe Commons sticks to that.
In a weakly typed language (eg Matlab) it would be another story.
If you aren't worried about SIMD optimisations and the like then I would have thought the best way would be to set up a templated tensor. Choose your maximum tensor dimensions and then you can do things like this:
typedef Tensor3D< float, 4, 1, 1 > Vector4;
And so forth. The mathematics, if implemented correctly, will just work with all forms of "matrix" and "vector". Both are, afterall, just special cases of tensors.
Edit: knowing the size of a template is actually pretty easy. Add in a GetRows() etc function and you can return the value you pass into the template at instantiation.
ie
template< typename T, int rows, int cols > class Tensor2D
{
public:
int GetRows() { return rows; }
int GetCols() { return cols; }
};
My advice? Don't worry about the 1x1 case and sleep at night. You shouldn't be worried about any uses suddenly deciding to use your library to model a bunch of numbers as 1x1 matricies and complaining about your implementation.
No one who solves these problems will be so foolish. If you're smart enough to use matricies, you're smart enough to use them properly.
As for all the permutations that scalars introduce, I'd say that you must account for them. As a matrix library user, I'd expect to be able to multiply two matricies together to get another matrix, a matrix by a (column or row) vector get a vector result, and a scalar times a matrix to get another matrix.
If I multiply two vectors I can get a scalar (inner product) or a matrix (outer product). Your library had better give them to me.
It's not trivial. It's been done "right" by others, but kudos to working it through for yourself.

Categories