Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This question already has an answer here:

Can anyone explain what is going on here? I want to modify TensorRank for IdentityMatrix, but it fails on its first attempt:

TensorRank[IdentityMatrix[_]] ^= 2;

UpSet::write: Tag IdentityMatrix in TensorRank[IdentityMatrix[_]] is Protected. >>



Unprotecting it for the second time does work however:

TensorRank[IdentityMatrix[_]] ^= 2;

This is on 9.0.1 for OS X, and I'm seeing the same behaviour on the cloud (version 10 for Linux).

share|improve this question

marked as duplicate by Mr.Wizard Oct 20 '14 at 16:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

It works fine for me in V10, Windows 8.1 – RunnyKine Aug 8 '14 at 8:37
Indeed, I can reproduce this under V10 on Linux – sebhofer Aug 8 '14 at 8:50
Confirmed in v9.0.1, Windows Vista 32bit. – xzczd Aug 8 '14 at 8:53
This is starting to look like a bug. Can anyone else confirm that the first attempt forks for V10 on Windows? – Teake Nutma Aug 8 '14 at 9:40
@sebhofer That makes sense, because TensorRank was introduced in V9. – Teake Nutma Aug 8 '14 at 10:47
up vote 7 down vote accepted

[Added: Virtually the same issue came up on StackOverflow a few years ago: Why do I have to evaluate this twice?]

I would not consider it a bug if the manipulation of System` variables do no go the way you want. It turns out that the definition of TensorRank is not loaded until it is first evaluated. That initialization process resets the attributes of IdentityMatrix.


ClearAttributes[TensorRank, ReadProtected]

?? TensorRank

TensorRank[tensor] gives the rank of tensor. >>

  Attributes[TensorRank] = {Protected}

  TensorRank := System`Dump`AutoLoad[Hold[TensorRank],
   Hold[Grad,...,SymmetrizedArray],SymbolicTensors`SymbolicTensors`] /; System`Dump`TestLoad

The initial definition shows that the actual definition is auto-loaded when TensorRank is evaluated.

For what it's worth, you can UpSet the value of TensorRank[IdentityMatrix[_]] in one go by evaluating TensorRank first. In general, therefore, for similar sorts of redefinition of System` symbols, the symbols should be evaluated first.

IdentityMatrix; (* unnecessary, but following my own advice above *)

TensorRank[IdentityMatrix[_]] ^= 2;
(* no messages *)

(* 2 *)
share|improve this answer
Thanks for the explanation. It still looks like a bug to me though: why would the autoloading of TensorRank reset properties of IdentityMatrix? – Teake Nutma Aug 8 '14 at 11:08
@TeakeNutma Something like: Unprotect[IdentityMatrix]; (* make some new definitions *); Protect[IdentityMatrix]. The code seems to be in a .mx file, so I can't say specifically. I doubt the code would check the attributes and then reset them to what they were. Since IdentityMatrix is in fact a tensor, it is not surprising to me that the symbolic tensor code fiddles with it. (Evaluating TensorRank loads all the symbolic tensor code; the same thing happens if you evaluate TensorProduct or another such function.) – Michael E2 Aug 8 '14 at 12:20
@MichaelE2 it looks like this is a bug. check the documentation example it is working fin from the first run before loading Log. I have faced same issue with Plus and Times. – Algohi Aug 8 '14 at 16:02
@Algohi I think it is a conscious, intentional decision. But that is my personal opinion and we don't have to agree. The Log example is not strictly equivalent. TensorRank loaded a package that reset the attributes on IdentityMatrix; other functions may also reset attributes. The documentation does not guarantee that once an attribute is changed, it won't be changed again. BTW, another ref. is…. – Michael E2 Aug 8 '14 at 16:29

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