1
$\begingroup$

I am trying to put all my functions in a single package and some of them do not work because of differentiation. Suppose I have the following package

BeginPackage["Diff`"] 
Diff[yy_]:=Module[{cc},cc=D[yy,x[1]];cc];
End[]
EndPackage[]

And suppose I do the following

<<Diff`
Diff[x[1]^2]

I expect to get 2x[1], but I get 0, what is going on? Probably I am missing something very simple. And yes I need variables in the form x[1],x[2],..., not x,y,z. Interestingly everything works perfectly fine if I do it without packaging:

Diff[yy_]:=Module[{cc},cc=D[yy,x[1]];cc];
Diff[x[1]^2]

The last operation gives 2x[1].

$\endgroup$
5
  • $\begingroup$ Dif[yy_, xx_] := Module[{cc}, cc = D[yy, xx]; cc]; and then Dif[x[1]^2, x[1]] ? $\endgroup$ Aug 3, 2015 at 3:48
  • $\begingroup$ I need to differentiate with respect to x[1],x[2],.... (many if them), I can define a list of variables and then differentiate with respect to each element, but then it is a lot of rewriting. I am just curious why I cannot differentiate with respect to smth like x[1] inside a package. $\endgroup$
    – Yuri
    Aug 3, 2015 at 4:43
  • $\begingroup$ I am curious if it is impossible or I just do not know how to do it. I am new with packages. $\endgroup$
    – Yuri
    Aug 3, 2015 at 4:47
  • 2
    $\begingroup$ As written, you should get 2 x[1], not 0. Is what you've written your actual package code? If you are actually putting Diff in a Private context, then you would get 0. $\endgroup$ Aug 3, 2015 at 5:04
  • $\begingroup$ @SimonRochester is right, thank you! $\endgroup$
    – Yuri
    Aug 3, 2015 at 5:16

1 Answer 1

5
$\begingroup$

If you define Diff in a private context, like

BeginPackage["Diff`"]
Diff::usage = ""
Begin["`Private`"]
Diff[yy_] := Module[{cc}, cc = D[yy, x[1]]; cc];
End[]
EndPackage[]

then you will get

<< Diff`

Diff[x[1]^2]
(* 0 *)

That's because the x referred to in the package is in the Diff`Private` context:

Definition@Diff // InputForm
(* Diff[Diff`Private`yy_] := Module[{Diff`Private`cc}, 
Diff`Private`cc = D[Diff`Private`yy, Diff`Private`x[1]]; Diff`Private`cc] *)

and so it's not the same x that you are calling Diff with, which is in the Global context:

Context[x]
(* "Global`" *)

To solve this, you can declare the x in your package to be in the Diff` context like so:

BeginPackage["Diff`"]
Diff::usage = ""
x::usage = ""
Begin["`Private`"]
Diff[yy_] := Module[{cc}, cc = D[yy, x[1]]; cc];
End[]
EndPackage[]

Since Diff` is put on the $ContextPath by EndPackage, when you refer to x after loading the package, it is translated to Diff`x, which matches the definition in the package (Make sure you restart the kernel first, if you're following along):

<< Diff`

Diff[x[1]^2]
(* 2 x[1] *)
$\endgroup$

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