3
$\begingroup$

I couldn't find much info about this problem so jumping right in: I have a large data matrix that I wish to select parts of and view in real-time using manipulate. But in coding it up I've found some odd behavior of manipulate when I try to make a function out of it using SetDelayed. For example, the following code works very quickly and presumably as intended:

rawdata = Table[{i, i + 1, i + 2}, {i, 100000}];
Manipulate[rawdata[[y;y+200]], {y, 500}]

The data matrix I'm using is about as large, but ordinarily there would be more selection criteria than a single element--however not an unreasonably complicated selection process: only a few criteria using one iteration of Cases[] for particular numeric values.

In any case, the aberrant behavior appears in this toy example when I wish to define the manipulate as a function for more general use (ultimately for use in a package):

displaydata[rawdatavar_] := Manipulate[rawdatavar[[y;;y+200]], {y, 500}]
displaydata[rawdata]

This second example takes 0.14s compared to the previous 0. In this specific example the evaluation time is short enough to not be too problematic but nevertheless demonstrates the strange behavior. With my real data however, despite only a difference of non-integer matrix elements and a use of Cases[] which separately behaves quickly, the evaluation time can be in tens of seconds or minutes.

Any insight or resources would be greatly appreciated. I am still somewhat a Mathematica novice so forgive me if this is a simple problem with the implementation of SetDelayed, but based on the documentation for Manipulate[] this should be valid.

Edit

Some interesting results: I've found that timing my minutes-long evaluation (using real data) only results in a 0.14 s duration. The rest of the time is apparently rendering the output. This is further explained because I get a temporary prompt window displaying "Formatting Notebook Contents". This appears to be the real problem--again any insight would be greatly appreciated.

$\endgroup$
  • $\begingroup$ I don't see much timing difference, but your syntax is weird -- you need something like {y, 10, 500, 1} (not {y,500}). After correcting this, both seem to work about the same. $\endgroup$ – bill s Oct 18 '16 at 1:21
  • $\begingroup$ Also there is a missing semicolon in Manipulate[rawdata[[y;y+200]], {y, 500}] on the first input block. $\endgroup$ – dan7geo Oct 18 '16 at 1:26
2
$\begingroup$

I see only a delay in the initial display of the second Manipulate. I expect it is because in the first, the data in accessed by reference, whereas in the second the whole of the data is incorporated into the DynamicModule constructed by the Manipulate.

Manipulate[rawdata[[y ;; y + 200]], {y, 500}] // ByteCount
(*  312  *)

displaydata[rawdata] // ByteCount
(*  2400464  *)

Once the second Manipulate is displayed, I find it updates just as quickly as the first.

Here's one way to get a "call-by-reference":

ClearAll[displaydata];
SetAttributes[displaydata, HoldAll];
displaydata[rawdatavar_] := Manipulate[rawdatavar[[y ;; y + 200]], {y, 500}];

displaydata[rawdata] // ByteCount
(*  312  *)
$\endgroup$
  • $\begingroup$ Yes, similar to the edit I made to the original question, this is also now what I find. This ultimately explains the problem, but any ideas on how to force accessing by reference in the SetDelayed case? Or do you have recommendations for reformulating the function to be useful with large matrices? $\endgroup$ – Erik Farr Oct 18 '16 at 1:36
  • $\begingroup$ @ErikFarr See my update. $\endgroup$ – Michael E2 Oct 18 '16 at 1:40
  • $\begingroup$ Thank you, this is exactly what I needed. I had been struggling with this for quite some time. $\endgroup$ – Erik Farr Oct 18 '16 at 1:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.