1

I've the following code:

Block[{Part}, 
   With[{x = #[[1]] + 1, y = #[[2]]}, 
    Hold[Pick[#[[All, 1 ;; 2]], #[[All, -1]], 0] &@
      NestList[
       With[{n = Sqrt[1 + 12 x^2 (1 + x)]}, 
         If[FractionalPart@n == 0, {x, Round[n], 0}, {x, y, 
           1}]] &, {Floor@CubeRoot@10^9, 1}, 10^(10)]]]] // 
  ReleaseHold // AbsoluteTiming

But this code gives an error message (SystemException["MemoryAllocationFailure"]), how can I solve it? And how can I speed up this calculation

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Jan Eerland
  • 2,001
  • 10
  • 17
  • What error message do you get? – mikado Jan 12 '20 at 14:52
  • Maybe this helps:https://mathematica.stackexchange.com/questions/212451/one-more-solution-of-the-mordell-equation – Mariusz Iwaniuk Jan 12 '20 at 14:53
  • @MariuszIwaniuk Can you help me implement the second code that MichaelE2 uses in his answer in the question you mention?! – Jan Eerland Jan 12 '20 at 14:59
  • @mikado I get SystemException["MemoryAllocationFailure"] – Jan Eerland Jan 12 '20 at 15:16
  • What exactly is the underlying problem to be solved? I ask because code that blocks Part automatically looks suspect. – Daniel Lichtblau Jan 12 '20 at 16:54
  • @DanielLichtblau I've to find values for x such that the square root of 1+12x^2(1+x) is an integer. I found this code using an answer given nu MivhaelE2 – Jan Eerland Jan 12 '20 at 16:56
  • The second argument to NestList is 10^10. That means a table of that length is preallocated. Which probably explains the memory exception. If brute-force is the only known approach for this computation, I will suggest instead using Do, Sow, and Reap. – Daniel Lichtblau Jan 12 '20 at 17:07
  • @DanielLichtblau yes I'm doing a brute force search but it takes so long using this method. Can you help me using a faster method to check – Jan Eerland Jan 12 '20 at 17:16
  • 1
    "As mentioned in the answer, this will break down if the search space goes beyond machine limits." -- the NestList will attempt to create a $10^{10} \times 3` array, which takes over 200 GB to store (if packed). I think you've gone beyond machine limits. – Michael E2 Jan 12 '20 at 17:20
  • 3
    Jan, note that Floor@CubeRoot@307. was to ensure that x^3 - 307 was positive (the first x is Floor@CubeRoot@307. + 1), because in that problem, we have n = Sqrt[x^3 - 307.]. In your problem, the corresponding starting point will be the least value of x that makes 1 + 12 x^2 (1 + x) positive. – Michael E2 Jan 12 '20 at 17:26
  • Another side remark: This brute-force approach has almost reached machine limits. If the approach is the best way to proceed, you are going to need something like a high-performance cluster, I think. – Michael E2 Jan 12 '20 at 17:28
  • Can you implement this in a way that rapidly does the calculations? Incrementally produce your candidates in lists of 10^6 using Table. That should be fast without needing 80+ gigabytes of memory. Use this https://stackoverflow.com/questions/295579/fastest-way-to-determine-if-an-integers-square-root-is-an-integer to quickly eliminate 7/8 of those numbers without needing to spend all the time doing square root calculations on every one. You need to implement that very carefully for that test to be fast. Then take the time to do square root on each remaining in the 10^6/8 – Bill Jan 12 '20 at 18:33
  • @Bill can you show a way to implement that? – Jan Eerland Jan 12 '20 at 18:41
  • I will leave the implementation up to you. You have been given lots of very clear input and hints on various ways to try to speed this up within the limits of your computer. Putting WAY too much memory in your computer might make it possible to ignore some optimizations and often makes things easier for Mathematica, but it seems that few consumer grade computers support 128 gigabytes of memory. – Bill Jan 12 '20 at 18:54

1 Answers1

4

This uses less memory:

Last@Reap@Do[
   With[{n = Sqrt[1 + 12 x^2 (1 + x) + 0``1]}, (* <-- N.B. *)
     If[FractionalPart@n == 0, Sow@{x, Round[n]}]] &,
   {x, 10^(10)}]

On my machine the first and last 10^6 iterations take about 0.4 seconds, so I project it might finish in less than an hour and a half.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Thanks for thinking with me. Is this a fast way to check? Or can there be an even faster way? – Jan Eerland Jan 12 '20 at 17:23
  • @Jan ParallelDo would probably cut the time in half on my machine, it seems, based a trial of 10^7 iterations. I can't think of a faster way right now if the search space (x up to or greater than 10^10) is going to be so large. Perhaps you could use some number theory to reduce the search space? – Michael E2 Jan 12 '20 at 17:33
  • can you show me the way to execute the code using ParallelDo? – Jan Eerland Jan 12 '20 at 17:35
  • So I can run: Last@Reap@ParallelDo[ With[{n = Sqrt[1 + 12 x^2 (1 + x) + 0``1]},If[FractionalPart@n == 0, Sow@{x, Round[n]}]] &, {x,10^9,10^(10)}] – Jan Eerland Jan 12 '20 at 17:37
  • there is no way to speed it up even faster? As far as you know – Jan Eerland Jan 12 '20 at 17:59
  • 1
    @Jan You keep asking the same question! You need to understand that the scale of your desired calculation is quite huge! You need to start thinking about alternatives: from the brute force perspective, you will soon need a computing cluster; perhaps better, though, would be to stop and think about it from first principles, and see if you can reduce the number of tries you need. – MarcoB Jan 12 '20 at 18:48