Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coupled and uncoupled states and operators #524

Merged
merged 9 commits into from Aug 26, 2011

Conversation

flacjacket
Copy link
Member

Implements coupled and uncoupled states, including logic to rewrite and represent these states and pass from one to the other. Coupling is done by passing j1 and j2 parameters to the represent or rewrite functions. Uncoupled states are taken as TensorProduct's of normal states.

Implements the logic for uncoupled operators and how operators, both coupled and uncoupled, act on the new states. Unocupled operators, like the uncoupled states, are defined by taking TensorProduct's of normal operators. These operators are able to then act on uncoupled states.

In addition, rewrite logic is changed to allow for symbolic states, both for symbolic j and for when the coupled parameters, j1 and j2, are symbolic.

One thing to note is for all the implemented spin space coupling, it is assumed there are only two coupled spin spaces, functions are not generalizable to higher spin spaces. The code to move up to coupling more spin spaces will be in a later pull.

Fixes:
http://code.google.com/p/sympy/issues/detail?id=2614

TODO:

@@ -169,7 +169,13 @@ def represent(expr, **options):
return represent(expr.base, **options)**exp
elif isinstance(expr, TensorProduct):
new_args = [represent(arg, **options) for arg in expr.args]
return TensorProduct(*new_args)
if options.get('coupled') is True:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base quantum modules like represent should not know anything about systems like spin. This spin dependent logic needs to be moved out of represent into spin.py in an appropriate place.

@ellisonbg
Copy link
Member

Some notes on this branch:

  • The logic in the SpinOpBase.apply_operator* methods has somehow gotten
    turned inside out. These methods all call _apply_op, which seem to handle
    cases where the ket is a non-Ket (Add,Mul,Sum). The apply_operator*
    methods are called by qapply and should never be passed anything than an
    instance of the class that matches the name of the method. Thus,
    _apply_operator_JzKet, must always be passed a JzKet instance. If these
    methods are getting passed anything different it is a bug in qapply
    and should be fixed. The logic here is also horribly circular. _apply_operator
    calls the _apply_operator_Foo methods, which call _apply_op, which calls
    _apply_operator.
  • The basis and basis_opts class attributes are being used by _apply_op, when
    the ket is rewritten. It is not clear why this rewriting is done and
    especially why some operators have coupled:True in basis_opts, but others
    don't.
  • It is also not clear when _apply_op is actually called as many subclasses
    override the _apply_operator_Foo methods.
  • We need to think about how to get specialized spin logic out of represent,
    TensorProduct and qapply.
  • I would like to better understand the logic in _rewrite_basis and the
    overall model of how spin coupling is being handled.

It would probably be best to have an IRC session about this. Is @certik around this week?

@flacjacket
Copy link
Member Author

In response to some points you made:

  • I pulled 'basis_opts', it was hanging around from when states could be defined as coupled, and given the current spin implementation isn't needed
  • I changed _apply_op to do less reinventing of the qapply wheel. The reason that was in place was because there is a rewrite step to get the state into a basis that the operator can act on the state, which could lead to a linear combination of states. Really, all apply_op does is write the state in a basis where the action of the operator on the state is known (i.e. a basis such that _apply_operator_Foo is overridden by the operator in question). There was some additional logic in _apply_op that was meant to deal with when there is a Sum returned by the rewrite for a symbolic state, but that could be something to do in qapply.
    I tried to push the coupling logic as far down as it made sense to do so without changing how things are currently implemented, but that and your other last couple points would probably be better discussed on IRC.

@asmeurer
Copy link
Member

Test results html report: http://pastehtml.com/view/b3im95u8t.html

Summary: There do not appear to be any problems.

Please double check this against the test report given above before merging with master.

Automatic review by sympy-bot.

@flacjacket
Copy link
Member Author

I have addressed all the things we discussed and was in the email. One thing, tho, is there are now some opperatorset tests that fail due to the new method of the SpinState class explicitly taking a j and m parameter, where the tests invoke it without any parameters. Maybe it's something @lazovich can comment on.

@lazovich
Copy link
Contributor

@flacjacket: This is something that is pretty easily fixed, I think. There's new code that I added in QExpr that will look for a default_args classmethod to try to fill in the args if a state is initialized with no parameters.

So, if you add something like this to SpinState it should solve the problem:

@classmethod
def default_args(self):
     return ("j", "m")

You can see cartesian.py for examples of how I have these in the continuous state classes.
You can also make those args Symbols explicitly if you'd like them to have certain assumptions with them. Otherwise, they'll just be sympified when you initialize the state.

If you don't want to add the default_args method, you should be able to just change the tests to invoke the state with explicit j and m arguments.

Hope that helps. Let me know if you have more questions!

@lazovich
Copy link
Contributor

@flacjacket: Actually, scratch that. I don't think the default_args solution will work because you override QExpr's new. The easiest solution is probably to just change the operatorset tests to pass an explicit j and m.

@lazovich
Copy link
Contributor

@flacjacket: Ah forgive the spam but as I think about this more I realize that the problem is actually a bit more subtle. Let me explain: operatorset.py has a dictionary which contains eigenstate to operator mappings, and vice versa. The whole point of this is to be able to call represent with basis=SomeOperatororSet or basis=SomeEigenket and have them do the same thing. The mapping functions in operatorset always try to return an instance of the thing they're mapping to, in this case a state. Here, the tests are expecting a "default" instance. The new in QExpr tries to call, as I mentioned before, a default_args method in the state if no parameters are passed. Since you're overriding new, one solution would be to add the default_args method as I suggested, and then change your new to check for it if no arguments are passed. (Rather than taking the j and m arguments explicitly in new, as you do now, you could just change the parameters to *args and then check the length).

Alternatively, since this doesn't directly affect your code for the time being, the easiest solution is probably to just comment out or delete the failing spin tests in operatorset and get this merged in. I'll then rebase on top of it and see if I can get default instances working in SpinState. (I have some other cosmetic changes to spin classes in my represent2 branch anyway, so this might be the best way to go).

@flacjacket
Copy link
Member Author

Thanks for the info Tomo, I've commented out the tests and now everything passes fine. If you need any help with the spin stuff, let me know. Any other comments or review would be great.

@asmeurer
Copy link
Member

@flacjacket, don't comment out tests. Use the XFAIL decorator.

Put the assert statements that you have commented out in a new function, and put @XFAIL above the function definition. You will need to import XFAIL from sympy.utilities.pytest. This way, the test runner will still try to run them, but will not bug you if they fail (XFAIL stands for "expected to fail"), but it will notify you if they start to pass.

@flacjacket
Copy link
Member Author

Thanks @asmeurer for noting that, the tests are now in an XFAIL

@certik
Copy link
Member

certik commented Aug 25, 2011

Test results html report: http://pastehtml.com/view/b51wt1xf9.html

Summary: There were test failures.

@flacjacket: Please fix the test failures.

Automatic review by sympy-bot.

@certik
Copy link
Member

certik commented Aug 25, 2011

Looking at the failures, it seems to me, that it's just 2**(1/2) -> sqrt(2) change. Was this some recent change in sympy?

@lazovich
Copy link
Contributor

Yes there was a recent change in the printing of sqrt. This affected my branch as well.

@flacjacket
Copy link
Member Author

Okay, I'll fix that when I get back from classes.

@asmeurer
Copy link
Member

@certik, yes, see my blog. This was a necessary and long awaited (by me) change, but unfortunately it is going to break half of the open pull requests. But they are trivial to fix, though, so no sweat.

Implements coupled and uncoupled states, including logic to rewrite and
represent these states and pass from one to the other through the
rewrite and represent functions. Also improves the handling of symbolic
states for rewriting. Coupled states are specified by taking normal
states and passing j1,j2 parameters to the represent or rewrite
functions. Uncoupled states are taken as TensorProduct's of normal
states.

Implements the logic for uncoupled operators and how operators, both
coupled and uncoupled, act on the new states. Unocupled operators, like
the uncoupled states, are defined by taking TensorProduct's of normal
operators. These operators are able to then act on uncoupled states.

For all the implemented spin space coupling, it is assumed there are
only two coupled spin spaces, functions are not generalizable to higher
spin spaces.
@flacjacket
Copy link
Member Author

This branch should now pass all the tests.

@certik
Copy link
Member

certik commented Aug 26, 2011

Test results html report: http://pastehtml.com/view/b54s54ok5.html

Summary: There do not appear to be any problems.

Please double check this against the test report given above before merging with master.

Automatic review by sympy-bot.

@certik
Copy link
Member

certik commented Aug 26, 2011

Looks good to me, merging.

certik added a commit that referenced this pull request Aug 26, 2011
Coupled and uncoupled states and operators
@certik certik merged commit 1e90da5 into sympy:master Aug 26, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants