Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a script written to test a package as follows:

SetDirectory[NotebookDirectory[]];
<< test`

A = {{1, 2}, {3, 4}}
cp = CharacteristicPolynomial[A, L]
sol = Sum[L[n, cp], {n, 0, 1}]

Which outputs "L+ Null".

The package is as follows:

BeginPackage["test`"]

L::usage="description goes here"

Begin["`Private`"]

ClearAll["Global`*"]

L[n0_,cp0_]:=
    Module[{n=n0,cp=cp0},
    L[n_,cp_]:=
        L[n,cp]=
            Which[
                n==0,L[0]=1,
                n==1,L[1]=L,
                n==2,L[2]=Simplify[-(cp-L^2)],
                n>2 && EvenQ[n]==True,L[n]=Simplify[L[n/2] L[n/2]],
                n>2 && EvenQ[n]==False,L[n]=Simplify[L[n-1] L[1]]
                ]
]

End[]
EndPackage[]

Essentially, my function "L[ ]" has 4 possible outputs:
when n=0 L[0]=1,
when n=1, L[1]=L,
when n=2, L[2]=Simplify[-(cp-L^2)]
when n>2 and even, L[n]=Simplify[L[n/2] L[n/2]]
when n>2 and odd, L[n]=Simplify[L[n-1] L[1]]

Why is L[0,cp]= Null, when all of the other possibilities work?
If I try just L[0,cp] (no Sum[ ]) I receive no output. What does that mean?
Is Which[ ] the best method of approach in this situation?

share|improve this question
1  
I would start with a single question and a minimal working example. Does having it as a package change anything? Are you sure you know, what are you doing with L[0]=1 etc.? –  Johu May 28 at 22:03
    
Check Definition["L"] and see, if it outputs what you expect. –  Johu May 28 at 22:12
1  
ClearAll["Global*"]` in a package??? –  Sjoerd C. de Vries May 28 at 23:34
    
The function looks rather bizarre to me. Memoization (L[n_,cp_]:= L[n,cp]=...)inside a scoping construct using the same variable names and then the whole Module SetDelayed to L again... Note that the n in Which is bound to the n in L[n_,cp_] and is not the same as the n in the Module variable list. So the first time it is called non of the Which tests is true and it returns Null. –  Sjoerd C. de Vries May 28 at 23:55
    
If I implement as just a function: L[n_, cp_] := L[n, cp] = Which[ n == 1, L[1] = L, n == 0, L[0] = 1, n == 2, L[2] = Simplify[-(cp - L^2)], n > 2 && EvenQ[n] == True, L[n] = Simplify[L[n/2] L[n/2]], n > 2 && EvenQ[n] == False, L[n] = Simplify[L[n - 1] L[1]] ] I get the correct output for any n. @Sjoerd C. de Vries I'm going to be honest, I have no idea what you are talking about. I'm be the first to admit I'm a beginner when it comes to Mathematica. Can you elaborate? –  gKirkland May 29 at 0:02

1 Answer 1

up vote 2 down vote accepted

There are a few issues here. I'll start with the little problems.

First, EvenQ returns True or False. You don't need to test whether EvenQ is true, so EvenQ[n]==True is redundantly redundant.

Next, what is L compared to L[n,cp]? Or L[1]? If your output in the second case of the Which is meant to be the function symbol L without any arguments specified, okay, but do you really mean L0 or some other initial value? Because you should use another symbol for that.

This need not be a module. A module allows you to define a routine that uses local variables and more complex programming techniques that operate on local variables. The only local variables you use are the inputs -- reassigned to be local variables.

The reason you don't want this to be a module, especially, is that your definition is:

L[n0_, cp0_] := Module[{n = n0, cp = cp0}, L[n_, cp_] := L[n, cp] =

That's one := too many. You don't even need memoization because (as far as I can tell) this is not meant to be recursive. The function L[_][_] seems to be constructed in a way that it assigns values to the (overloaded) function L[_]. Other comments have addressed this issue and have noted this is why you are not getting any output.

If you make the following changes, you'll have something functional (pun intended?):

L[n_?IntegerQ, cp_?IntegerQ] :=
 Which[
  n == 0, L[0] = 1,
  n == 1, L[1] = L,
  n == 2, L[2] = Simplify[-(cp - L^2)],
  n > 2 && EvenQ[n], L[n] = Simplify[L[n/2] L[n/2]],
  n > 2, L[n] = Simplify[L[n - 1] L[1]]
 ]

This function will only take integer inputs (that's what the ?IntegerQ will do). It will output some expression of other L functions. For example, L[3,7] will output L[1]L[2].

Now, you've still overloaded the symbol L substantially. Why is a two-argument L[3,7] giving us L[1]L[2], which is a product of some other type of L that takes only one argument?

I'm under the impression that we can fix this code so that it works, but it's not really doing what we want. I hope we've cleared up the technical issues, but we need to start from scratch.

EDIT: You can skip to the addendum here if you want to cut to the chase.

Mathematically, you seem to just one a single sequence L that is determined by some integer parameter cp. You can do this in a much more reasonable way by thinking of it this way:

For any integer $cp$, you have a sequence $L_n^{cp}$ that is defined recursively. You can write the appropriate code as follows:

L[cp_?IntegerQ][n_?IntegerQ] := L[cp][n] =
 Which[
  n == 0, 1,
  n == 1, L[cp][0],
  n == 2, L[cp][0]^2 - cp,
  n > 2 && EvenQ[n], Simplify[L[cp][n/2]^2],
  True, L[cp][n - 1] L[cp][1]
 ]

I've taken some liberty by using L[cp][0] instead of the no-argument L. You'll have to figure out what goes there. If that is some other parameter, you probably ought to give it a different name like \[Lambda] or something. (It would play a similar role as cp.)

This uses a sort of double-function, rather than two-argument function, for technical reasons. You could replace every occurrence of L[_][_] with L[_,_], but for programmatic reasons I think it's better the [_][_] way.

Try this to experiment:

Manipulate[Table[L[cp][n], {n, 1, 10}], {{cp, 1}, -10, 10, 1}]

On second thought, I'd like to pretend now that maybe this L with no arguments is a parameter. Let's not call it L to avoid confusion. Your code might look like:

L[cp_?IntegerQ, \[Lambda]_?IntegerQ][n_?IntegerQ] :=
 L[cp, \[Lambda]][n] =
 Which[
  n == 0, 1,
  n == 1, \[Lambda],
  n == 2, \[Lambda]^2 - cp,
  n > 2 && EvenQ[n], Simplify[L[cp, \[Lambda]][n/2]^2],
  True, L[cp, \[Lambda]][n - 1] L[cp, \[Lambda]][1]
 ]

Manipulate[
 Table[L[cp, \[Lambda]][n], {n, 1, 10}],
 {{cp, 1}, -10, 10, 1}, {{\[Lambda], 1}, -10, 10, 1}
]

ADDENDUM:

Upon further review, I didn't even read your example code (sorry, I am lazy sometimes in the worst ways). Apparently cp is a polynomial. In this case, why does it not have an argument? Based on this, here is my revised code:

I will say, in my opinion, this probably doesn't belong in an external file/package. And if it does, I think I would be cautious with the ClearAll[Global*]`. I suggest you remove that, at least, if not just putting everything into a single notebook for now.

I think I have finally deciphered exactly what you're trying to do.

Let's start from scratch, mathematically. You have a matrix $A$. This matrix has a characteristic polynomial, a function of $\lambda$. You have integers $n$ that will define some functions of $\lambda$ for each $n$. These are not functions of $cp$. They are functions of $A$ and $n$.

The sequence of polynomial functions of $\lambda$ you want are defined by:

$L_{A,0}(\lambda)=0$

$L_{A,1}(\lambda)=\lambda$

$L_{A,2}(\lambda)=\lambda^2-p_A(\lambda)$

$L_{A,2n}(\lambda)=L_{A,n}(\lambda)^2$

$L_{A,2n+1}(\lambda)=L_{A,2n}(\lambda)L_{A,1}(\lambda)$

This can be achieved by:

L[A_, n_] := L[A, n] =
 Function[\[Lambda],
  Which[
   n == 0, 1,
   n == 1, \[Lambda],
   n == 2, \[Lambda]^2 - CharacteristicPolynomial[A, \[Lambda]],
   n > 2 && EvenQ[n], Simplify[L[A, n/2][\[Lambda]]^2],
   True, L[A, n - 1][\[Lambda]] L[A, 1][\[Lambda]]
  ]
 ]

A = {{1, 2}, {3, 4}}
Table[L[A, n][\[Lambda]], {n, 0, 10}]
sol = Plus @@ %
Expand[%]

That should do whatever it is you're trying to do... I think.

share|improve this answer
    
Thank you! That's exactly what I wanted. I'll just forget about the package for now, and place everything into a notebook. Thanks also for showing how to use [Lambda], I didn't know you could do that (hence the use of "L"). –  gKirkland Jun 3 at 3:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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