Representing an integer as the sum of four squares - algorithm

Given a positive integer m, find four integers a, b, c, d such that a^2 + b^2 + c^2 + d^2 = m in O(m^2 log m). Extra space can be used.
I can think of an O(m^3) solution, but I am confused about the O(m^2 logm) solution..

First hint:
What is the complexity of sorting squared elemnt from 1 to m^2
Second hint:
Have a look at this post for some help :
Break time, find any triple which matches pythagoras equation in O(n^2)
Third Hint:
If you need more help : (from yi_H response on the previous post):
I guess O(n^2 log n) would be to sort the numbers, take any two
pairs (O(n^2)) and see whether there is c in the number for which c^2
= a^2 + b^2. You can do the lookup for c with binary search, that's
O(log(n)).
author: yi_H
Now compare n and sqrt(m)
Hope you can figure out a solution with this.

There is a classical theorem of Lagrange that says that every natural number is the sum of four squares.
The Wikipedia page on this topic mentions that there is a randomized algorithm for computing the representation that runs in O(\lg^2 m) time (all the suggestions above are polynomial in m, i.e., they are exponential in the size of the problem instance (since the number m can be encoded in \lg m bits).
As an aside, Lagrange's theorem proves the undecidability of the integers with plus and times (since the naturals are undecidable, and can be defined in the integers with plus and times, by virtue of the theorem).

Related

Does the asymptotic complexity of a multiplication algorithm only rely on the larger of the two operands?

I'm taking an algorithms class and I repeatedly have trouble when I'm asked to analyze the runtime of code when there is a line with multiplication or division. How can I find big-theta of multiplying an n digit number with an m digit number (where n>m)? Is it the same as multiplying two n digit numbers?
For example, right now I'm attempting to analyze the following line of code:
return n*count/100
where count is at most 100. Is the asymptotic complexity of this any different from n*n/100? or n*n/n?
You can always look up here Computational complexity of mathematical operations.
In your complexity of n*count/100 is O(length(n)) as 100 is a constant and length(count) is at most 3.
In general multiplication of two numbers n and m digits length, takes O(nm), the same time required for division. Here i assume we are talking about long division. There are many sophisticated algorithms which will beat this complexity.
To make things clearer i will provide an example. Suppose you have three numbers:
A - n digits length
B - m digits length
C - p digits length
Find complexity of the following formula:
A * B / C
Multiply first. Complexity of A * B it is O(nm) and as result we have number D, which is n+m digits length. Now consider D / C, here complexity is O((n+m)p), where overall complexity is sum of the two O(nm + (n+m)p) = O(m(n+p) + np).
Divide first. So, we divide B / C, complexity is O(mp) and we have m digits number E. Now we calculate A * E, here complexity is O(nm). Again overall complexity is O(mp + nm) = O(m(n+p)).
From the analysis you can see that it is beneficial to divide first. Of course in real life situation you would account for numerical stability as well.
From Modern Computer Arithmetic:
Assume the larger operand has size
m, and the smaller has size n ≤ m, and denote by M(m,n) the corresponding
multiplication cost.
When m is an exact multiple of n, say m = kn, a trivial strategy is to cut the
larger operand into k pieces, giving M(kn,n) = kM(n) + O(kn).
Suppose m ≥ n and n is large. To use an evaluation-interpolation scheme,
we need to evaluate the product at m + n points, whereas balanced k by k
multiplication needs 2k points. Taking k ≈ (m+n)/2, we see that M(m,n) ≤ M((m + n)/2)(1 + o(1)) as n → ∞. On the other hand, from the discussion
above, we have M(m,n) ≤ ⌈m/n⌉M(n)(1 + o(1)).

Calculating the constant attached to the asymptotic complexity of heap and merge sorts

I programmed both a merge and a heap sort and calculated the runtime complexity, I am suppose to now find the constant c for merge and heap sort from the data I collected (c*(n*lg(n))). The following are the two graph formulas (from excel) of the number of elements (n) vs. runtime (seconds), how would I calculate the c constant? Any help will be appreciated! Thank you.
Heap:
y = 5E-12x2 + 2E-05x - 0.0561
Merge:
y = 9E-10x2 - 9E-05x + 2.0958
The formulas you've given are polynomials of the form f(n) = an2 + bn + c with constants a, b, and c. These aren't going to help you.
You need to fit an equation of the form f(n) = an lg(n) + bn + c to your data. Not a polynomial, but an equation with an n lg(n) term in it. The coefficient of that term is what you've been asked for. The linear (b) and constant (c) terms don't matter. Just the constant on the n lg(n) term since it grows the fastest.

Break time, find any triple which matches pythagoras equation in O(n^2)

I think it's interesting to solve this in holiday:
Given n integers, all of them within 1..n^3, find if there is a triple which matches pythagoras equation in O(n^2).
As you know pythagoras equation is a^2 + b^2 = c^2. for example 3^2 + 4^2 = 5^2.
As you know O(n^2 log n) is easy (with a little thinking), but will help to solve O(n^2). (space is not important).
Edit: As yi_H offered there is lookup table which can solve this problem easily, but for making it harder, space limit is O(n^2).
O(n2) time, O(n) space: square all array elements, sort, for each z in the array use the classic linear-time algorithm to determine whether there exist x, y in the array such that x + y = z.
All pythagorean triplets (a,b,c) have the following relation:
a = d * (2 * m * n)
b = d * (m^2 - n^2)
c = d * (m^2 + n^2)
where
d >= 1 and (m,n) = 1
(meaning: m and n have no comomn factor.
I guess one can find an algorithm to produce all triplets that are below n^3 using this info.
I guess O(n^2 log n) would be to sort the numbers, take any two pairs (O(n^2)) and see whether there is c in the number for which c^2 = a^2 + b^2. You can do the lookup for c with binary search, that's O(log(n)).
Now if space isn't an issue you can create a hash for all the values in O(n), then you can look up c in this hash with O(1), so it's going to be O(n^2). You can even create an lookup table for it since the numbers are between 1..n^2, so it's going to be a guaranteed O(1) lookup ;) You can also use a special lookup table which can do initialization, add and lookup in O(1).

Disjoint sets with forest implementation without path compression

Consider a forest implementation of disjoint sets with only the weighted union heuristics (NO PATH COMPRESSION!) with n distinct elements. Define T(n,m) to be the worst case time complexity of executing a sequence of n-1 unions and m finds in any order, where m is any positive integer greater than n.
I defined T(n,m) to be the sequence of doing n-1 unions and then m finds AFTERWARDS because doing the find operation on the biggest tree possible would take the longest. Accordingly, T(n,m) = m*log(n) + n - 1 because each union takes O(1) so n-1 unions is n-1 steps, and each find takes log(n) steps per as the height of the resultant tree after n-1 unions is bounded by log_2 (n).
My problem now is, does the T(n,m) chosen look fine?
Secondly, is T(n,m) Big Omega (m*log(n)) ? My claim is that it is with c = 1 and n >= 2, given that the smallest possible T(n,m) is m*log(2) + 1, which is obviously greater than m*log(2). Seems rather stupid to ask this but it seemed rather too easy for a solution, so I have my suspicions regarding my correctness.
Thanks in advance.
Yes to T(n, m) looking fine, though I suppose you could give a formal induction proof that the worst-case is unions followed by finds.
As for proving that T(n, m) is Ω(m log(n)), you need to show that there exist n0 and m0 and c such that for all n ≥ n0 and all m ≥ m0, it holds that T(n, m) ≥ c m log(n). What you've written arguably shows this only for n = 2.

Squaring n-bit int vs. multiplying two n-bit ints

Disclaimer: Homework question. I'm looking for a hint…
Professor F. Lake tells his class that it is asymptotically faster to square an n-bit integer than to multiply two n-bit integers. Should they believe him?
I believe that multiplying two n-bit ints via shift/add is an O(n) operation, but I can't see why squaring an n-bit int would be any different. Am I missing something?
Since you wanted only a hint, answer comes from this equation: (a + b)^2 = a^2 + b^2 + 2*a*b
To not spoil the puzzle, I've posted complete solution separately :)
Imagine that squaring is actually asymptotically faster. Then if you have a * b, you could calculate:
a = m + n
b = m - n
Then solving this equation system gives:
m = (a+b)/2
n = (a-b)/2
But then we have
a * b = (m+n)*(m-n) = m² - n²
or without intermediate variables:
a * b = ((a+b)² - (a-b)²)/4
So you can replace any multiplication by two squaring operations (and some additions and division by 4, which is just a bit shift, and these can be all ignored for asymptotical complexity). So the complexity of multiplication is at most twice the complexity of squaring. Of course, "twice" is a constant factor, which means both have the same asymptotical complexity.
Here's a hint.
And here's my solution in SECRET CODE:Fdhnevat zrnaf lbh bayl unir gb qb bar vavgvny SG, abg gjb, fb vg'f snfgre.
Consider the steps the computer needs to take in order to accomplish these tasks. Remember that computers work drastically different from people.
My thought is that to multiply two n-bit integers your algorithm needs to cater for any two n-bit integers. That's (2^n)^2 possible inputs.
A squaring algorithm only needs to handle 2^n possible inputs, although it can be modelled as a multiply algorithm with two inputs the same.
My guess is that there would be some way to optimise the generic multiply algorithm when you know that both inputs will be the same, but I'd have to think about it. That's the line I'd be investigating, anyway...
Rewritten: This is the only improvement that I can see in squaring a n-bit number over multiplying two n-bit numbers together. It may not be asymptotically better in the O(n^2) vs. O(n) sort of way that is commonly used in computer science. However, if we take it asymptotically literally meaning the complexity that is approached (including the multiplicative constants), then this will fit that definition. Anyway, it's all that I can see to do so take it or leave it.
Let's say that we have two N-bit numbers, x and y. We can multiply them together (x*y) with the shift-and-add method with A*N^2 + O(N) operations where A is a constant. The second term, the O(N) term, can be disregarded for large enough N so the number of operations is essentially A*N^2.
Now we calculate x^2. If we define a to have only the upper N/2 bits of x set in it and b to have only the lower N/2 bits of x set in it, then
x = a + b
x^2 = (a + b)^2 = a^2 + b^2 + 2*a*b
However, remember that we can multiply a N-bit number with A*N^2 operations. To multiply a*a we only have to do A*(N/2)^2 = A*N/4 operations. The same goes for b*b and a*b. If we ignore the O(N) operations, then x^2 = (a + b)^2 is calculated in
A*N^2/4 + A*N^2/4 + A*N^2/4 = (3/4)*A*N^2
operations which is of course better than the standard A*N^2 for multiplying two arbitrary N-bit numbers by A*N^2/4. We can further improve on this by repeating the same operation with a^2 and b^2. At some point it will not be beneficial to keep doing this. This is not an enormous improvement, but it's all that I can find. You can decide for yourselves if this counts or not.

Resources