# Function in notebook vs function in package?

Posted 4 months ago
699 Views
|
5 Replies
|
3 Total Likes
|
 Hi all,I started to write a package for my project, where I put all the useful functions and then import the package to use them. Problems arise, so here is the function:The function is used to generate odes to use in NDSolve MakeSystem[var_, vart_, sys_]:= Module[{v, vt, S, St, Sf}, v = var; vt = vart; S = sys; St = S/.Thread[v-> vt]; Thread[D[vart, t] == St]] This is an example to use the function: dndt = r * (1 - k * n) * n - c * n * p; dpdt = c * n * p; var = {n, p}; vart = {n[t], p[t]} system = {dndt, dpdt}; MakeSystem[var, vart, system] If I put the function in the notebook, it produces exactly what I want: n'[t] == r * (1 - k * n[t]) * n[t] - c * n[t] * p[t] p'[t] == c * n[t] * p[t] But if I put the function in the package, the D[vart, t] produces zeros, so the output is 0 == r * (1 - k * n[t]) * n[t] - c * n[t] * p[t] 0 == c * n[t] * p[t] Any help?
5 Replies
Sort By:
Posted 3 months ago
 Your variable t is the problem. It shows up "raw" in several places. When you put your MakeSystem definition inside of a package, that t will not be in the Global' context, but in whatever context your package uses, so it might be something like Test'Private't (btw, all of the ' should be backticks) You end up producing a derivative of an expression with respect to a variable that isn't in that expression, and such a derivative will evaluate to 0.One fix would be to ask the caller to provide the symbol, so add a fourth argument to MakeSystem that is expected to be the symbol/variable with respect to which we're going to take the derivative. The problem with this is that you need to make sure you use the same variable in vart, but that's also a good thing, because it makes the intent very explcit.
Posted 3 months ago
 Actually, you could just get rid of vart altogether--it can be constructed from var and the new argument. I would have called the new argument var, but... :)
Posted 3 months ago
 And since I started making refactoring suggestions, I guess I'll continue... You also don't need Module. A couple of simplifications would lead to: MakeSystem[fnNames_List, var_, rhs_List] := With[ {fns = Through[fnNames[var]]}, Thread[Equal[D[fns, var], rhs /. Thread[fnNames -> fns]]]] 
Posted 3 months ago
 Thanks a lot Eric for the solution.Yup, that's what I also suspect about the parameter t. I'm just not sure how to handle it.
Posted 3 months ago
 The code I posted above handles it. I could make it clearer by using pattern matching on var: MakeSystem[fnNames_List, var_Symbol, rhs_List] := With[{fns = Through[fnNames[var]]}, Thread[Equal[D[fns, var], rhs /. Thread[fnNames -> fns]]]] Now using your data: MakeSystem[{n, p}, t, {r*(1 - k*n)*n - c*n*p, c*n*p}] (*{Derivative[1][n][t] == r n[t] (1 - k n[t]) - c n[t] p[t], Derivative[1][p][t] == c n[t] p[t]} *)