I want to know whether equation set has a solution, and I use solve(f)!=[] (python sympy) to achieve it. But I only need to know that whether there is a solution so I do not need to find all the solutions which will consume a lot of time. Is there any way to do it efficiently?
Be aware that sympy.solve giving [] doesn't necessarily mean the equation has no solution. It only means it could not find any. Some equations have solutions but they cannot be expressed in closed form (like cos(x) = x). sympy.solveset will give you the full solutions but in cases where it can't tell it will just return a generic solution set.
As to the original question I don't know if there's a way to do it in general. If you are only dealing with real continuous functions you could check if it is strictly positive or strictly negative on its domain. Sympy doesn't have the strongest tools for checking this, without some user assistance.
Related
I'm using sympy to generate expressions like this:
for crowd in itertools.combinations(symbs, max_true + 1):
exprs.append(functools.reduce(operator.and_, crowd))
unaltered = ~functools.reduce(operator.or_, exprs)
Later, I convert them to CNF:
altered = sympy.logic.boolalg.to_cnf(unaltered, simplify=True, force=True)
It takes a lot of computer time. I made a gist with more details:
https://gist.github.com/MatrixManAtYrService/501ea099826a5aeeacc9368710b059ec
Given that I'm generating expressions with for loops, they're in a reliable format. Sympy (understandably) is doing the exhaustive thing and solving them "by hand", because it doesn't know that they're so well behaved. A human who is looking at the unaltered/altered expressions can easily ascertain the pattern and just generate the CNF directly with a for loop.
That's easy enough in this case, but I expect to have more constraints.
I want to know if I'm in uncharted terratory, or just failing to ask for help correctly.
Does Sympy have anything to help with this kind of thing? Is there another library I should explore? Is there a name for the "look at it and extrapolate based on a pattern" strategy that I'm proposing? Is there a list of algorithms for the task somewhere?
I have a set of problems (sets of equations and inequalities) for which I know that all variables have to be integers, and have finitely many solutions. I know that if I take any random objective function and let an lp or mip solver onto it, it finds a solution, however I want all solutions to the problem, and of course, as efficiently as possible. I don't really care about optimizing anything, but apparently most of the software that deals with it does. Is there any solver that can do that? If so, which one is the best/simplest one, or which one would you recommend? At best one that can be used as a C/C++ library.
There is a nice blog post by Paul Rubin on how to find K best solutions, which can be easily generalized to get all the solutions. As Ali suggested one of the approaches is to use a solution pool. Two other approaches are:
Use an incumbent callback to track and reject solutions.
Use an incumbent callback with solution injection.
See the blog post for details.
IBM ILOG CPLEX has a solution pool feature and it's free for academic purposes.
I guess you can probably get all solution if you set the maximum pool size sufficiently large. I don't know for sure, never tried.
I am new to gecode and constraint programming in general.
So far, I haven't had much trouble picking up gecode, it's great. But I was wondering what is the best way to perform a "nested" cost function. Specifically, I am looking to minimize X, but within the space of solutions for which X is equal, prefer solutions which minimize Y? I could probably hack it by defining a cost function that looks like X*large_number+Y, but I'd prefer to do this properly if there's a good solution.
If anyone can point me to explain how to implement this in Gecode, that would be really helpful. Thanks!
You can define any kind of optimization criteria using the constrain member in a space in Gecode. See Section 2.5 in Modeling and Programming with Gecode for an example. In your case, the straight forward way would be to add a constrain member that adds a lexicographic constraint between the previous best solutions answer and the current space.
That being said, in general optimizing based on a lexicographic order can be wasteful (too much searching). It may often be better to first run a search optimizing the first component (X in your case). After that, re-run the search with the first components value fixed (X set to best possible value), and optimize the second value (Y in your case). Iterate as needed for all elements in the cost.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I am looking for C++ open-source library (or just open-source Unix tool) to do: Equality test on Equations .
Equations can be build during runtime as AST Trees, string or other format.
Equations will mostly be simple algebra ones, with some assumptions about unknown functions. Domain, will be integer arithmetic (no floating point issues, as related issues are well known - Thanks #hardmath for stressing it out, I've assumed it's known).
Example: Input might contain function phi, with assumptions about it (most cases) phi(x,y)=phi(y,x) and try to solve :
equality_test( phi( (a+1)*(a+1) , a+b ) = phi( b+a, a*a + 2a + 1 )
It can be fuzzy or any equality test - what I mean is that, it does not have to always succeed (It may return "false" even if equations are equal).
If there would be problem with supporting assumptions like above about phi function, I can handle this, so just simple linear algebra equations equality testers are welcome as well.
Could you recommend some C/C++ programming libraries or Unix tools ? (open-source)
If possible, could you attach some example how such equality test, might look like in given library/tool ?
P.S. If such equality_test could (in case of success) return isomorphism - (what I mean, a kind of "mapping") - between two given equations, would be highly welcome. But tools without such capabilities are highly welcome as well.
P.S. By "fuzzy tester" I mean that in internals equation solver will be "fuzzy" in terms of looking for "isomorphism" of two functions, not in terms of testing against random inputs - I could implement this, for sure, but I try to find something with better precision.
P.P.S. There is another issue, why I need better performance solution, than brute-force "all inputs testing". Above equation is simplyfied form of my internal problem, where I do not have mapping between variables in equations. That is, I have eq1=phi( (a+1)*(a+1) , a+b ) and eq2=phi( l+k, k*k + 2k + 1 ) , and I have to find out that a==k and b==l. But this sub-problem I can handle with "brute-force" approach (even asymptotic complexity of this approach), case there is just a few variables, let it be 8. So I would need to do this equation_test for each possible mapping. If there is a tool that that whole job, I would be highly thankful, and could contribute to such project. But I don't require such functionality, simply equation_test() will be enough, I can handle rest easily.
To sum it up:
equality_test() is only one of many subproblems I have to solve, so computational complexity matters.
it does not have to be 100% reliable, but higher likelihood, than just testing equations with a few random inputs and variable mapping is highly welcome :).
output of "yes" or "no" (all additional information might be useful but in future, at this stage I need "Yes"/"No")
Your topic is one of automated theorem proving, for which a number of free/open source software packages have been developed. Many of these are meant for proof verification, but what you ask for is proof searching.
Dealing with the abstract topic of equations would be the theories mathematicians call varieties. These theories have nice properties with respect to the existence and regularity of their models.
It is possible you have in mind equations that deal specifically with real numbers or other system, which would add some axioms to the theory in which a proof is sought.
If in principle an algorithm exists to determine whether or not a logical statement can be proven in a theory, that theory is called decidable. For example, the theory of real closed fields is decidable, as Tarski showed in 1951. However a practical implementation of such an algorithm is lacking and perhaps impossible.
Here are a few open source packages that might be worth learning something about to guide your design and development:
Tac: A generic and adaptable interactive theorem prover
Prover9: An automated theorem prover for first-order and equational logic
E(quational) Theorem Prover
I am not sure for any library but how about you do it yourself by generating a random set of inputs for your equation and substituting it in both equations which have to be compared. This would give you a almost correct result given you generate considerable amount of random data.
Edit:
Also you can try http://www.wolframalpha.com/
with
(x+1)*(y+1) equals x+y+xy+2
and
(x+1)*(y+1) equals x+y+xy+1
I think you can get pretty far with using Reverse Polish Notation.
Write out your equation using RPN
Apply transformations to bring all expressions to the same form, e.g. *A+BC --> +*AB*AC (which is the RPN equivalent of A*(B+C) --> A*B+A*C), ^*BCA --> *^BA^CA (i.e. (B*C)^A --> B^A * C^A)
"Sort" the arguments of symmetric binary operator so that "lighter" operations appear on one side (e.g. A*B + C --> C + A*B)
You will have problem with dummy variables, for example sum indices. There is no other way, I think, but to try every combination of matching them on both sides of the equation.
In general, the problem is very complicated.
You can try a hack, though: use an optimizing compiler (C,Fortran) and compile both sides of the equation to optimized machine code and compare the outputs. It may work, or may not.
Opensource (GPL) project Maxima has tool simmilar to Wolfram Alpha's equals tool :
(a+b+c)+(x+y)**2 equals (x**2+b+c+a+2*x*y+y**2)
Which is is(equal()), that solves formulas :
(%i1) is(equal( (a+b+c)+(x+y)**2 , (x**2+b+c+a+2*x*y+y**2) ));
(%o1) true
For this purpose, it uses rational simplifier - ratsimp, in order to simplify the difference of two equations. When difference of two equations is simplified to zero, we know they are equal for all possible values:
(%i2) ratsimp( ((a+b+c)+(x+y)**2) - ((x**2+b+c+a+2*x*y+y**2)) );
(%o2) 0
This answer, just shows direction (like other answers). If you know about something similar, that can be used as a part of C++ Unix program - programming library ? Good C/C++ binding similar tool to this. Please, post new answer.
I need to solve a few mathematical equations in my application. Here's a typical example of such an equation:
a + b * c - d / e = a
Additional rules:
b % 10 = 0
b >= 0
b <= 100
Each number must be integer
...
I would like to get the possible solution sets for a, b, c, d and e.
Are there any libraries out there, either open source or commercial, which I can use to solve such an equation? If yes, what kind of result do they provide?
Solving linear systems can generally be solved using linear programming. I'd recommend taking a look at Boost uBLAS for starters - it has a simple triangular solver. Then you might checkout libraries targeting more domain specific approaches, perhaps QSopt.
You're venturing into the world of numerical analysis, and here be dragons. Seemingly small differences in specification can make a huge difference in what is the right approach.
I hesitate to make specific suggestions without a fairly precise description of the problem domain. It sounds superficiall like you are solving constrained linear problems that are simple enough that there are a lot of ways to do it but "..." could be a problem.
A good resource for general solvers etc. would be GAMS. Much of the software there may be a bit heavy weight for what you are asking.
You want a computer algebra system.
See https://stackoverflow.com/questions/160911/symbolic-math-lib, the answers to which are mostly as relevant to c++ as to c.
I know it is not your real question, but you can simplify the given equation to:
d = b * c * e with e != 0
Pretty sure Numerical Recipes will have something
You're looking for a computer algebra system, and that's not a trivial thing.
Lot's of them are available, though, try this list at Wikipedia:
http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems
-Adam
This looks like linear programming. Does this list help?
In addition to the other posts. Your constraint sets make this reminiscent of an integer programming problem, so you might want to check that kind of thing out as well. Perhaps your problem can be (re-)stated as one.
You must know, however that the integer programming problems tends to be one of the harder computational problems so you might end up using many clock cycles to crack it.
Looking only at the "additional rules" part it does look like linear programming, in which case LINDO or a similar program implementing the simplex algorithm should be fine.
However, if the first equation is really typical it shows yours is NOT a linear algebra problem - no 2 variables multiplying or dividing each other should appear on a linear equation!
So I'd say you definitely need either a computer algebra system or solve the problem using a genetic algorithm.
Since you have restrictions similar to those found in linear programming though you're not quite there, if you just want a solution to your specific problem I'd say pick up any of the libraries mentioned at the end of Wikipedia's article on genetic algorithms and develop an app to give you the result. If you want a more generalist approach, then you've got to simulate algebraic manipulations on your computer, no other way around.
The TI-89 Calculator has a 'solver' application.
It was built to solve problems like the one in your example.
I know its not a library. But there are several TI-89 emulators out there.