2

I'm creating a notebook with a Manipulate and I'm trying to call/use a function from another notebook (I use Get for that), in which the function is also inside a Manipulate... but my "main" notebook wouldn't "see" that function.

I have also added LocalizedVariables -> False in the "slave" notebook, with no improvement. Of course I have created a package (*.m) from the "slave" notebook and put the right path for it in Get.

There must be some limitations, which I'm not aware of, of using this kind of calling functions from another notebook, right?

Example of (very simple) code:

Mfunction.nb (& Mfunction.m)

Manipulate[
func[a_, x_] := Sin[a*x];
Plot[func[a, x], {x, 0, 2*Pi}],
{a, .1, 10, 0.1, Appearance -> "Labeled"},
LocalizeVariables -> False]

Mmain.nb

Manipulate[
Plot[1/func[b, y], {y, 1, 100}],
{b, 1, 20, .1, Appearance -> "Labeled"},
Initialization :> (
Get["(* Path *)//Mfunction.m"];)]
Kuba
  • 136,707
  • 13
  • 279
  • 740
Conrad
  • 723
  • 4
  • 10

1 Answers1

1

Manipulate is HoldAll and the body isn't evaluated till it is displayed. That's because effectively there is Dynamic[body]. I once explained that a little in Manipulate in Manipulate.

So inside the package it won't do anything, as no output is generated. You can see this here:

ClearAll[x];

Manipulate[x = 5, {y, Null}];
Pause[1];
x

Manipulate[x = 5, {y, Null}]
Pause[1];
x

The first x doesn't have a value because Manipulate wasn't displayed (;).


The way to go is to move your definitions outside of a Manipulate.

A quick but not general fix would be to load those packages while temporarily hiding Manipulate's attributes. This can by done with Block:

Initialization :> (Block[{Manipulate}, Get@"../Mfunction.m"];)

At the end but you can read some tutorials about the package creation in documentation or here:

Creating Mathematica packages

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • my goal is to re-use functions, already defined in some calculation tools I've created in Mathematica, without needing to re-define them in my new notebook or copy/paste the corresponding, available code in it. I also want to avoid to modify the code in the referenced notebooks, as they are already deployed in form of .cdf files. So as I understood, it's not possible to achieve this goal, right? – Conrad Apr 05 '16 at 13:37
  • 1
    @Conrad no, it's not. You have to do something like: func[a_, x_] := Sin[a*x]; Manipulate[Plot[func[a, x], {x, 0, 2*Pi}],{a, .1, 10, 0.1}] but the you need Savedefinitions or something so that the old Manipulate will remember them. – Kuba Apr 05 '16 at 13:40
  • @Conrad this is not general but will this work for you: Block[{Manipulate}, Get @ path ] instead of pure Get? – Kuba Apr 05 '16 at 13:52
  • no, it doesn't work unfortunately. I tried both to put the Block[] section under Initializationand also directly at the beginning of Manipulate, without success... – Conrad Apr 05 '16 at 14:43
  • @Conrad like: Initialization :> (Block[{Manipulate}, Get["../Mfunction.m"]];)]? Does .m file contain those Manipulates a all? – Kuba Apr 05 '16 at 14:47
  • yes, actually I did Initialization :> (Block[{Manipulate}, Get@"../Mfunction.m"];) , but after that I also tried exactly as you write... – Conrad Apr 05 '16 at 14:52
  • The .m file contains of course the Manipulate . – Conrad Apr 05 '16 at 14:53
  • @Conrad don't have more time to check your setup but it seems to work in general: (ClearAll[f]; Block[{Manipulate}, Get[#]]; Close[#]) & @ StringToStream@"Manipulate[f[x_]:=1;x,{x,0,1}];" – Kuba Apr 05 '16 at 14:59
  • could you please put your proposal directly in my code? I don't really understand how to use it. After that I promise I will not bother you any longer on this topic ;-) . – Conrad Apr 06 '16 at 07:23
  • @Conrad This is only a minimal example that blocking manipulate should work when you are using get on the package with functions inside manipulates. Don't worry about StringToStream stuff, it is there because I can't use Get on a string yet I wanted to create minimal example. – Kuba Apr 06 '16 at 07:30
  • It works, I managed to make the main notebook "see" the function, by using the Block[{Manipulate}, Get[path]]. Thank you so much! Could you please put this solution in form of an answer, to be able to choose it accordingly? – Conrad Apr 06 '16 at 09:20
  • @Conrad Great, done :) – Kuba Apr 06 '16 at 09:29