Problems with Polynomial.java zeros method - java

Here is the location of the source code (using Dropbox).
The problem is in the fact that it doesn't evaluate zeros properly.
For example: x^2-2x-8 should equal the zeros of {-4, 2}, but instead I get a long exponential value like -4+34534....E-25<i>i</i>.
It does work for polynomials with single roots (such as x<sup>2</sup>+4x+4, root = {-2})
Can anyone spot the problem, it's been frustrating me for weeks. This is NOT a homework assignment, this is something I work on in my free time.

I've run into problems like this before and decided to switch to a different (math-oriented) language. You could try using floats instead of doubles, which may do the trick, but would probably bear problems of their own. Or you could write a method that filters out anything smaller than 1E-10 or something along those lines. Another alternative (which may or may not be relevant here) would be to use JLink.

Related

What would be the best way to build a Big-O runtime complexity analyzer for pseudocode in a text file?

I am trying to create a class that takes in a string input containing pseudocode and computes its' worst case runtime complexity. I will be using regex to split each line and analyze the worst-case and add up the complexities (based on the big-O rules) for each line to give a final worst-case runtime. The pseudocode written will follow a few rules for declaration, initilization, operations on data structures. This is something I can control. How should I go about designing a class considering the rules of iterative and recursive analysis?
Any help in C++ or Java is appreciated. Thanks in advance.
class PseudocodeAnalyzer
{
public:
string inputCode;
string performIterativeAnalysis(string line);
string performRecursiveAnalysis(string line);
string analyzeTotalComplexity(string inputCode);
}
An example for iterative algorithm: Check if number in a grid is Odd:
1. Array A = Array[N][N]
2. for i in 1 to N
3. for j in 1 to N
4. if A[i][j] % 2 == 0
5. return false
6. endif
7. endloop
8. endloop
Worst-case Time-Complexity: O(n*n)
The concept: "I wish to write a program that analyses pseudocode in order to print out the algorithmic complexity of the algorithm it describes" is mathematically impossible!
Let me try to explain why that is, or how you get around the inevitability that you cannot write this.
Your pseudocode has certain capabilities. You call it pseudocode, but given that you are now trying to parse it, it's still a 'real' language where terms have real meaning. This language is capable of expressing algorithms.
So, which algorithms can it express? Presumably, 'all of them'. There is this concept called a 'turing machine': You can prove that anything a computer can do, a turing machine can also do. And turing machines are very simple things. Therefore, if you have some simplistic computer and you can use that computer to emulate a turing machine, you can therefore use it to emulate a complete computer. This is how, in fundamental informatics, you can prove that a certain CPU or system is capable of computing all the stuff some other CPU or system is capable of computing: Use it to compute a turing machine, thus proving you can run it all. Any system that can be used to emulate a turing machine is called 'turing complete'.
Then we get to something very interesting: If your pseudocode can be used to express anything a real computer can do, then your pseudocode can be used to 'write'... your very pseudocode checker!
So let's say we do just that and stick the pseudocode that describes your pseudocode checker in a function we shall call pseudocodechecker. It takes as argument a string containing some pseudocode, and returns a string such as O(n^2).
You can then write this program in pseudocode:
1. if pseudocodechecker(this-very-program) == O(n^2)
2. If True runSomeAlgorithmThatIsO(1)
3. If False runSomeAlgorithmTahtIsO(n^2)
And this is self-defeating: We have 'programmed' a paradox. It's like "This statement is a lie", or "the set of all sets that do not contain themselves". If it's false it is true and if it is true it false. [Insert GIF of exploding computer here].
Thus, we have mathematically proved that what you want is impossible, unless one of the following is true:
A. Your pseudocode-based checker is incorrect. As in, it will flat out give a wrong answer sometimes, thus solving the paradox: If you feed your program a paradox, it gives a wrong answer. But how useful is such an app? An app where you know the answer it gives may be incorrect?
B. Your pseudocode-based checker is incomplete: The official definition of your pseudocode language is so incapable, you cannot even write a turing machine in it.
That last one seems like a nice solution; but it is quite drastic. It pretty much means that your algorithm can only loop over constant ranges. It cannot loop until a condition is true, for example. Another nice solution appears to be: The program is capable of realizing that an answer cannot be given, and will then report 'no answer available', but unfortunately, with some more work, you can show that you can still use such a system to develop a paradox.
The answer by #rzwitserloot and the ones given in the link are correct. Let me just add that it is possible to compute an approximation both to the halting problem as well as to finding the time complexity of a piece of code (written in a Turing-complete language!). (Compare that to the existence of automated theorem provers for arithmetic and other second order logics, which are undecidable!) A tool that under-approximated the complexity problem would output the correct time complexity for some inputs, and "don't know" for other inputs.
Indeed, the whole wide field of code analyzers, often built into the IDEs that we use every day, more often than not under-approximate decision problems that are uncomputable, e.g. reachability, nullability or value analyses.
If you really want to write such a tool: the basic idea is to identify heuristics, i.e., common patterns for which a solution is known, such as various patterns of nested for-loops with only very basic arithmetic operations manipulating the indices, or simple recursive functions where the recurrence relation can be spotted straight-away. It would actually be not too hard (though definitely not easy!) to write a tool that could solve most of the toy problems (such as the one you posted) that are given as homework to students, and that are often posted as questions here on SO, since they follow a rather small number of patterns.
If you wish to go beyond simple heuristics, the main theoretical concept underlying more powerful code analyzers is abstract interpretation. Applied to your use case, this would mean developing a mapping between code constructs in your language to code constructs in a different language (or simpler code constructs in the same language) for which it is easier to compute the time complexity. This mapping would have to conform to some constraints, in particular, the mapped constructs have have the same or worse time complexity as the original code. Actually, mapping a piece of code to a recurrence relation would be an example of abstract interpretation. So is replacing a line of code with something like "O(1)". So, the task is just to formalize some of the things that we do in our heads anyway when we are analyzing the time complexity of code.

Exponentional function parameters

I have 3 points [x0 y0], [x1 y1], [x2 y2] with strict conditional x0<x1<x2, y0<y1<y2. All this points lay on some exponentional functions y=ae^(bx)+c. I need to find a,b,c... It's not possible to solve system of 3 equations precisely, therefore I need to approximate it. Is there some math library in java that will help me solve this problem? I find something similar on mathcad
https://help.ptc.com/mathcad/en/index.html#page/PTC_Mathcad_Help/exponential_regression.html but not find in java.
Other way - how to solve system of 3 equations and 3 values approximately.
ae^(bx_0)+c=y_0
ae^(bx_1)+c=y_1
ae^(bx_2)+c=y_2
You have to solve a system of non-linear equations, for which only an approximate solution is possible but can be done using the Newton Raphson's Multivariate method.
The algorithm is, quite frankly, a notational pain but you can go through it here -
http://fourier.eng.hmc.edu/e176/lectures/NM/node21.html.
What is happening essentially is you have a function whose derivative lead you to an 'equilibrium' from an initial random point (which you guess as a possible root)
If you are not willing to write the code yourself this repo can give you a starter of sorts - https://github.com/prasser/newtonraphson.
But AFAIK, no ready library exists for this purpose. You can use Wolfram's Mathematica or MATLAB/OCTAVE for ready libraries though.
That said, here are a few other (more complicated) things you can look into
https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm
https://www1.fpl.fs.fed.us/optimization.html
http://icl.cs.utk.edu/f2j/
http://optalgtoolkit.sourceforge.net/
http://scribblethink.org/Computer/Javanumeric/index.html
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html
Hope this helps!

BigDecimal precision above 1E22

for some reason I found myself coding some piece of software, that should be able to perfom some astronomic calculations.
While most of it will be about transfering the correct formula into Java, I found an annoying Problem right at the verry beginning of my "test how to calculate big numbers".
Well... Imagine the Sun (our Sun), which has a mass of (about and rounded, for more easy explaining) 10E30 kg. Ten with 30 following Zeros. All native datatypes are just unusuable for this. To mention: I KNOW that I could use 3000 to calculate things and just add trailing zeros in the output-view, but I hoped to keep it as precise as possible. So using short numbers will be my last resort only.
Comming to the Problem. Please have a look at the code:
BigDecimal combinedMass = new BigDecimal(1E22);
int massDistribution = 10;
Integer mD1 = massDistribution;
Integer mD2 = 100 - massDistribution;
BigDecimal starMass;
BigDecimal systemMass;
systemMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD1.toString()));
starMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD2.toString()));
System.out.println((systemMass).toEngineeringString());
System.out.println((starMass));
It will output 1000000000000000000000 and 9000000000000000000000, whats exactly what I did expect. But look at the combineMass Field. If I raise it to 1E23, the Output will change
I get 9999999999999999161139.20 and 89999999999999992450252.80...
So I know I could use jut BigInteger, because its more reliable in this case, but for the sake of precicion, sometimes the BigWhatEver may drop to something like 50.1258
Plus, I hope to get the 10.xE30 as output, whats only possible using bigDecimals.
I want to know: Is there no way avoidng this (that error appers above 1E23 for every value I tried), while keeping the ability to calculate Floating-Points? Should I cut the After-Decimal-Separator-Values for this Field to two digets?
And for something more to wonder about:
System.out.println(combinedMass.precision());
in relation with the code above will provide 23 for that case, but En+1 for most other values (Thats was when I grow really confused)
Thanks for advise.
You're using basic types without realizing it:
new BigDecimal(1E22);
Here, 1E22 is a primitive double, and you already lost precision by using it.
What you want is
new BigDecimal("10000000000000000000000");
or
new BigDecimal(10).pow(22);

Combinatorics in Java with trees

For a project that I'm currently working on I am dealing with a list of lists of integers, something of the form:
{[1,2];[5];[3,6,7]}
The idea here is that I'm trying to resolve an n-dimensional array into a list of the local maxima that occur in whatever particular axis I happen to be looking at. My question is this: I would like to get out a list of what would essentially be points in this n-dimensional space that contains every possible combination of entries of this list. For example, I would want the above to return:
{[1,5,3];[1,5,6];[1,5,7];[2,5,3];[2,5,6];[2,5,7]}
With the ordering not actually mattering to me. My first idea in how to approach this would be to boil this down to a tree where each path represents a possible combination and outputting every possible path, but I'm really not sure if this is the best way of going about it, and I am unfamiliar enough with Java's tree classes to be unsure if this would actually be straightforward to implement or not. Ideas?
Ah, my mistake, totally a duplicate.

Trying to create a stack calculator in Java

I have to keep in mind the priority of operations, all the numbers including the answer are integers (seems silly to me but whatever), and I have to parse a String for the equation and, as far as I'm aware, push each number and each operator in two different stacks before I compare them.
I don't know how to approach this problem, and right now my main concern is dealing with parentheses. I want to use a recursive method to solve the calculation which would check for parentheses and solve them and replace them with their result, but I'm not sure how to do that. I could use substring() and indexOf() but I'd rather be more elegant.
Other than that I'm not sure how to solve the calculation once numbers and operators are stacked. I think I should compare the top 2 operators to make sure that if I combine two numbers, it is in the right order of operations, but I don't want to be clumsy with that part either.
My recommendation would be that you study the Shunting-yard algorithm and come back when you have specific questions about how it works or how to implement certain parts of it.

Categories