Ok, I have it up and running now. I didn’t have pylab installed so I removed the plot routine. I’ll post a solutions file tomorrow.

]]>Klas,

See the function ‘optim’ in this new version:

It works similarly to the other function except that it’s all in one. I think it’s clear enough how to separate out the bits that construct the program, solve it, and interpret it.

]]>Klas: yes, I think I do. I don’t have access to it at the moment, but I can upload it when I get home this evening.

]]>Alec, do you still have the general program which allows general rectangles rather than only squares in the decomposition?

]]>i have added the datafiles from last nights computer work.

The file data-file-N contains the best solutions for N up to 142, with the interval size at most N and no weight restrictions.

The file data-file-30-max2=0-2 continas a few more solutions in the same sequence as data-file-30-max2=0

]]>Alec I have not had time to examine the solutions closely enough to see if that is the only difference. I believe you can produce some examples to compare by just solving for some small N and taking maximum size 10 first and then 30.

I am now running a loop which solves for increasing N, with no weight restriction, and maximum allowed size equal to N. I’ll probably have solutions up N around 140 by tomorrow.

]]>On the existence of several optima: if the solution contains

then this group of terms can always be replaced by

or any convex combination of the two. Have you noticed any pairs of optima that differ in other ways? Perhaps one could force the solution into a ‘canonical’ form by adding a small adjustment to the quantity being minimized, in a consistent way.

On the oval as an edge effect: it’s worth mentioning that that pattern remains optimal up to at least .

A small, perhaps obvious, observation is that the weight of the solutions does tend to be concentrated at the lower end of the range. So perhaps we should be looking for patterns there.

]]>I have now added the solutions file for maximum weight 0 and size at most 30.

I have been making files for N up to 200 but this can be extended without too much effort.

The loop which I am running now also seems to improve at smooth numbers, it is at N=118 right now, and I think that was the case for several of the earlier files too. But I haven’t examined the solutions. I’ll post the new solutions files tomorrow morning.

One thing which could be interesting to do, but I don’t know if the cvxop package has any routines for it, would be to find all optimal solutions for some combination of N, max size and max weight. I have observed that sometimes the solutions, but not the value of c, changes when the maximum size of a square is increased.

If there are several optimal solutions we might not be seeing the most structured ones now.

Klas, I find your latest solutions file interesting. Here, just for easy reference, is a list of places where the record for is broken by what seems to be a real amount rather than an artefact of the numerical algorithm. I’ll list the integer where the new record occurs and what the record is. I’ll also give rational approximations (which I think are in fact the “real” values rather than the decimals that precede them). Note that the process starts at

It’s hard to decide from that evidence alone what these numbers will do eventually, but whatever it is they’re doing they seem to set records at smooth numbers, and they also quite like moderate-sized primes such as 7, 11 and 13. I haven’t stared at the record-setting examples to see how they are exploiting these numbers.

]]>That is indeed interesting. I wonder whether the intuitive explanation for the oval is that it is a sort of edge effect — because the example is forced to stop at 186 it has to do ugly things when it finds a nice smooth number near there.

Indeed, having asked that question, I wonder whether there might be some kind of “simulated annealing” approach to finding examples, where you would initially aim to get quite a lot of cancellation without worrying about every last detail, and would then have a kind of trade-off between changing what you’ve done so far (which you are reluctant to do) and getting more cancellation (which you want to do). In this example, one might do a crude version such as, say, looking for bigger examples that agree with this one up to 100.

]]>I have added another solutions file, for maximum weight 0.5 on 2×2 and size at most 30.

Tonight the program will run maximum weight 0 with size at most 30.

Alec, if it is easy to do I think adding coordinates to the pictures you make would be helpful.

]]>The solutions where blocks are completely forbidden are interesting. One can do a bit better by increasing the maximum size of the interval. For example, with and intervals up to size , one can get .

A plot of this example is here:

You need to zoom in to see the detail, but there are some interesting features, like the expensively-constructed ‘oval’ formation hovering above .

No problem: I had a moment of inspiration, so that typo held me up much less than my general incompetence at doing anything at all along these lines.

]]>Oops, sorry about the mis-spelling Tim. Glad you figured it out!

]]>I have to correct a mistake I made. The last two files were not for size at most 12, but rather at most 7. I forgot to change the size when I moved to program. I have renamed the two solution files accordingly.

I am also producing a solution file for total weight of 2×2 at most 0.5 and size at most 30.

]]>Thanks for that — after considerable effort I have managed to dig out that it was XCode that I used to create Python files, and then followed that up by dealing with several mysterious error messages until I finally got your code to work. (A few of the things that I was doing wrong — I had to sort out whether it was the contents of the curly brackets that needed inserting or those plus the curly brackets, and whether the square brackets should be removed, and the fact that it should be “print_solution” instead of “print_solutions”, and the fact that if the numbers weren’t rational enough I needed to try a smaller example. But I know that this kind of thing is absolutely par for the course, especially for someone with my levels of inexperience.) Anyhow, just to prove I managed it, here is one of Klas’s examples:

(1, 3) : 8

(2, 5) : 8

(2, 6) : -8

(3, 5) : 4

(4, 6) : 20

(5, 7) : 16

(6, 8 ) : 8

(6, 10) : -4

(7, 10) : 4

(9, 10) : 47

(10, 12) : 19

(10, 13) : 16

(10, 15) : -16

(11, 15) : 16

(12, 14) : 7

(12, 16) : -8

(13, 15) : 16

(13, 16) : 8

(14, 15) : 19

(14, 16) : 4

(15, 17) : 15

(19, 21) : 23

(20, 23) : 12

(20, 24) : -12

(22, 25) : 12

(22, 26) : -12

(23, 26) : 12

(24, 25) : 3

(24, 29) : 16

(24, 30) : -16

(29, 30) : 39

(30, 31) : 19

(30, 36) : -19

(31, 36) : 19

(38, 41) : 23

(38, 42) : -23

(41, 42) : 23

(44, 51) : 4

(44, 52) : -4

(45, 49) : 8

(45, 50) : -12

(45, 52) : 4

(46, 49) : 4

(46, 51) : -4

(47, 49) : -12

(47, 50) : 12

(48, 49) : 15

(48, 52) : -15

(49, 52) : 15

(54, 59) : 23

(54, 60) : -23

(59, 60) : 23

Yes, that method works for small examples, but not for some of the larger ones. I tried it on the last entry in ‘data-file-12-max2=0.125’; the first number turned out to be well approximated by 28/1389, but mutiplying through by 1389 didn’t make the others into near-integers.

As efficiency isn’t much of an issue in this case, I’ve gone with my naive method, with the proviso that we stop trying after a certain point.

I’ve uploaded a new version of the code here:

It includes the following functions:

def print_solution(lam): for I in sorted(lam.iterkeys()): print I, ":", lam[I] # nearest integer nint = lambda x : -nint(-x) if x < 0 else (int(x) + (0 if x%1 < 0.5 else 1)) def to_integer(lam, m_max = 1000, eps = 0.01): """ Convert solution to one with integer coefficients, if possible. m_max is the largest integer multiplier we're willing to consider. eps is how close the scaled-up values have to be to integers. Return the integer solution if possible, or None otherwise. """ l_vals = lam.values() n_vals = len(l_vals) m = 0 m_ok = False while (m <= m_max) & (not m_ok): m += 1 i = 0 i_ok = True while (i < n_vals) & i_ok: x = m * l_vals[i] i_ok = (abs(x - nint(x)) < eps) i += 1 m_ok = i_ok # multiply though by m return dict((I, nint(m*lam[I])) for I in lam) if m_ok else None

Tim, if you have Python installed (as I think you said you did), you should be able to use this on the solutions that Klas has already published. It doesn’t need any extra modules.

Copy and paste the code above into a file, and save it as (for example) ‘convert.py’.

At the bottom of the file, add the line:

print_solutions(to_integer([stuff in curly braces pasted from Klas' output]))

For example:

print_solutions(to_integer({(1, 2): 0.33333333333333276, (3, 4): 0.33333333333333376, (2, 3): 0.33333333333333343, (2, 4): -0.33333333333333304}))

Run the file:

python convert.py

It should print out (for this example):

(1, 2) : 1 (2, 3) : 1 (2, 4) : -1 (3, 4) : 1

If you want to change the defaults for how far to go and how close to an integer the multiples must be, change the last line to (for example):

print_solutions(to_integer([stuff pasted], m_max=2000, eps=0.001))

(the defauts are 1000 and 0.01).

]]>A much more efficient method, which I tried by hand on one of the examples (or rather, with an on-screen calculator) is to use continued fractions. That is, you keep taking reciprocals and fractional parts until you suddenly hit something that’s surprisingly close to an integer, and then you work out what that means your original number must have been close to. I managed to discover that a certain decimal was extremely close to 167/145 this way, for instance.

]]>The following function will output the result with the intervals sorted in increasing order:

def print_solution(lam): for I in sorted(lam.iterkeys()): print I, ":", lam[I]

So you could do something like:

result = interpret(x, I_list) print_solution(result['lam'])

I’m not sure how to do the conversion to integers algorithmically. We’d need some function that takes a vector , and presumably some ‘tolerance’ parameter, and outputs an integer such that is ‘near enough’ to . I suppose one could simply try positive integers in turn until , where is the distance from to the nearest integer. I’ll see if something like that works …

]]>I have added two solution files for even lower total weight of the 2×2 squares.

]]>Alec, can you implement Tims suggestions regarding how to present the solutions?

I think it might be a good idea to make a separate program which can read a solutions file of the kind have posted and transform it into a second updated file. That way we don’t have to redo any of the computations.

I should have explained how to read the plot. It shows the main diagonal and points above it, rotated so that the main diagonal is the bottom horizontal. In other words, the point in the solution, where , is represented as the point in the image.

]]>Here is an example of a plot produced from Klas’ example with and the total weight of the coefficients of the blocks constrained to be at most :

(I suggest saving it to your computer and viewing it in some sort of image viewer.) Blues are positive (darker more so) and reds are negative (darker more so). The colour mapping could be improved, but in this example it gives some idea of what’s going on.

]]>I’ve written a function to produce and save a plot of the solution. It’s in this new version:

]]>