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

Inconsistent indices don't lead to error #108

Open
eschnett opened this issue Mar 20, 2014 · 5 comments
Open

Inconsistent indices don't lead to error #108

eschnett opened this issue Mar 20, 2014 · 5 comments

Comments

@eschnett
Copy link
Collaborator

I had the following expression in a calculation:

    dot[B[ua]] -> IfB[+ dotXt[ua]
                      + IfThen[fixAdvectionTerms!=0,
                               Upwind[beta[ub], Xt[ua], lb],
                               0]
                      - (betaDriverValue
                         (+ B[ua]
                          + IfThen[fixAdvectionTerms!=0 && advectShift!=0,
                                   Upwind[beta[ub], beta[ua], la] /
                                   (shiftGammaCoeffValue alpha^shiftAlphaPower),
                                   0]))
                      + IfThen[fixAdvectionTerms==0 && advectShift!=0,
                               Upwind[beta[ub], B[ua], lb],
                               0]
                      + Dissipation[B[ua]],
                      0],

Note that the index "la" appears in there (in the second Upwind term), which it should not, as the respective subexpression then has index "ub" free, inconsistent with the left-hand side. "la" needs to be replaced by "lb".

This did not lead to an error.

Upwind is defined as follows:

Upwind[dir_, u_,il_] := dir PDua[u,il] + Abs[dir] PDus[u,il];

Is there a way to declare functions taking tensor indices?

@ianhinder
Copy link
Owner

I believe the problem is that the checking code doesn't know what to make of IfB, or indeed IfThen. As far as TensorTools is concerned, these are just functions. How should TensorTools handle unknown functions? Should it insist that each argument has the same free indices? Sometimes the first argument of IfThen will have the same indices as the second and third argument, but sometimes it will be a scalar expression. It looks like TensorTools needs extra information about specific functions in order to know what is valid.

@eschnett
Copy link
Collaborator Author

There are some expressions that "eat tensors", such as MatrixOfComponents. In other cases, the functions should probably be treated as element-wise non-linear transformations of tensor components. In the case of IfThen[a,b,c], the condition a should not have any tensor indices, and the branches b and c must conform to each other. In this sense, "conform" means that scalars may be promoted to tensors. Similar properties hold for Max[a,b] and Min[a,b].

@barrywardell
Copy link
Collaborator

I encountered a similar IfThen problem recently while tidying up the xTensor support in Kranc. Since xTensor does more strict error checking than TensorTools, and xTensor didn't know how to handle IfThen, it complained with some standard Kranc scripts such as McLachlan (I think it would also have picked up the problem mentioned above).

The solution I came up with was the following:

  1. "Factor out" the conditionals within the right hand side. What I mean by this is that I turned all possible branches (since there can be multiple, possibly nested IfThen's) into a single switch, with one right hand side for each possible branch of the switch.
  2. Check each individual right hand side for tensor-correctness (including the left hand side)
  3. Expand out components for each right-hand side separately.
  4. Turn the result into the form, where all possible branches are represented:
lhs -> IfThen[condition1 && condition2, rhs1true2true, IfThen[condition1 && !condition2, rhs1true2false, ...]]

Step 4 might also be better implemented in some other way, e.g. pulling the conditional out further to get a set like IfThen[condition1 && condition2, lhs -> rhs1true2true, IfThen[condition1 && !condition2, lhs -> rhs1true2false, ...]], or similar, but I thought this would have required more extensive changes to Kranc.

@barrywardell
Copy link
Collaborator

PS. The implementation is in xTensorKranc.m and could probably be ported to TensorTools relatively easily.

@eschnett
Copy link
Collaborator Author

The latter step can be implemented as an optimization. Common expressions can be pulled out of conditionals. They can also be pulled out of other expressions such as Max or Min, but one has to be careful there. Pulling common expressions out of sums could lead to a large performance benefit, if we can e.g. re-constitute (a+b+c)*(e+f+g) from its expanded, distributed version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants