I’m running a Table function which will take too much time to complete.
I wanted to know if there’s a way to retrieve the results computed so far.
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
The proposed solution
Here is a version of
Tablethat isAbort-able and will keep the intermediate results collected so far. It is a modified version of the solution posted here.It should be able to take the same iterator specification as
Table.How it works
Here is how it works. The first statement (
SetDelayed @@...) “parses” the iterators, assuming that they are each of the form{iteratorSymbol_,bounds__}, and assigns the list of iterator variables to the variableindices. The construction withHoldis needed to prevent possible evaluation of iterator variables. There are many ways to do this, I used just one of them. Here is how it works:Using
SetDelayed @@ the-abovewill then naturally produce the delayed definition of the formindices:={i,j,k}. I assigned the values to indicesi,j,kto demonstrate that no unwanted evaluation of them happens when using this construct.The next statement produces a list of collected results, where each result is grouped in a list with the list of indices used to produce it. Since
indicesvariable is defined by delayed definition, it will evaluate every time afresh, for a new combination of indices. Another crucial feature used here is that theDoloop accepts the same iterator syntax asTable(and also dynamically localizes the iterator variables), while being a sequential (constant memory) construct. To collect the intermediate results,ReapandSowwere used. Sinceexprcan be any piece of code, and can in particular also useSow, a custom tag with a unique name is needed to onlyReapthose values that wereSownby our function, but not the code it executes. SinceModulenaturally produces (temporary) symbols with unique name, I simply used aModule– generated variable without a value, as a tag. This is a generally useful technique.To be able to collect the results in the case of
Abort[]issued by the user interactively or in the code, we wrap theDoloop inCheckAbort. The code that is executed onAbort[]({}here) is largely arbitrary in this approach, since the collection of results is anyway done bySowandReap, although may be useful in a more elaborate version that would save the result into some variable provided by the user and then re-issue theAbort[](the functionality not currently implemented).As a result, we get into a variable
indexedResa flat list of the formwhere the results are grouped with the corresponding index combination. We need these index combinations to reconstruct the multi-dimensional resulting list from a flat list. The way to do it is to repeatedly split the list according to the value of
i-th index. The functionSplitByhas this functionality, but we need to provide a list of functions to be used for splitting steps. Since the index ofi-th iterator index in the sublist{expr,{ind1,...,indn}}is2,i, the function to do the splitting ati-th step is#[[2, i]]&, and we need to construct the list of such functions dynamically to feed it toSplitBy. Here is an example:The
With[{i=i},body]construct was used to inject the specific values ofiinside pure functions. The alternatives to inject the value ofiintoFunctiondo exist, such as e.g.:or
or
but are probably even more obscure (perhaps except the last one).
The resulting nested list has a proper structure, with sublists
{expr,{ind1,...,indn}}being at level-3(third level from the bottom). By usingMap[First,lst,{-3}], we remove the index combinations, since the nested list has been reconstructed already and they are no longer needed. What remains is our result – a nested list of resulting expressions, whose structure corresponds to the structure of a similar nested list produced byTable. The last statement is wrapped inAbortProtect– just in case, to make sure that the result is returned before the possibleAbort[]fires.Example of use
Here is an example where I pressed
Alt+.(Abort[]) soon after evaluating the command:It is almost as fast as
Table:But it does not auto-compile while
Tabledoes:One can code the auto-compilation and add it to the above solution, I just did not do it since it will be a lot of work to do it right.
EDIT
I rewrote the function to make some parts both more concise and easier to understand. Also,
it is about 25 % faster than the first version, on large lists.