The problem with the original code is an evaluation problem. @Henrik points this out in a comment.
The rule t -> 0
becomes 0.2 -> 0
in the call U[0.2]
:
Hold[U[0.2]] /. DownValues@U
(*
Hold[Total[(With[{x$ = Normalize[#1]},
x$ \[TensorProduct] (x$ /. 0.2 -> 0)] &) /@ Eigenvectors[H[0.2]], 1]]
*)
However the rule is applied to the eigenvectors of H[0.2]
, which do not contain a 0.2
to replace:
Eigenvectors[H[0.2]]
(* {{0.540734, -0.841193}, {-0.841193, -0.540734}} *)
It's different in the call U[t]
, in which the rule is t -> 0
and the eigenvectors of H[t]
contain a t
to replace with zero.
One way around the difficulty is to use a different symbol for t
in H[t]
. Formal symbols cannot normally be assigned a value, so \[FormalT]
is a good candidate:
UU[t_] := With[{v = Normalize /@ Eigenvectors[H[\[FormalT]]]},
Total[MapThread[
TensorProduct, {v /. \[FormalT] -> t, v /. \[FormalT] -> 0}], 1]
];
Since Eigenvectors[H[t]]
is always the same, one might want to precompute the formulas for U[t]
and use them to define the function U
. It's a good idea to protect t
with Block
, in case it has been assigned a value. Also, it turns out formal symbols can be assigned a value by a user with Block[{\[FormalT] = 5}, <code>]
, so it would be even safer to use Module
to create a temporary symbol for H[t]
:
Block[{t},
UU[t_] = Module[{$t, v},
v = Normalize /@ Eigenvectors[H[$t]];
Total[MapThread[TensorProduct, {v /. $t -> t, v /. $t -> 0}], 1]
]
];