@@ -165,8 +165,12 @@ function inds(kwargs::NamedTuple{(:bond,)}, tn::AbstractAnsatz)
165
165
return only (inds (tensor1) ∩ inds (tensor2))
166
166
end
167
167
168
- # TODO fix this properly when we do the mapping
169
- tensors (kwargs:: NamedTuple{(:at,),Tuple{L}} , tn:: AbstractAnsatz ) where {L<: Lane } = tensors (tn; at= Site (kwargs. at))
168
+ # TODO fix this properly when we do the mapping
169
+ function tensors (kwargs:: NamedTuple{(:at,),Tuple{L}} , tn:: AbstractAnsatz ) where {L<: Lane }
170
+ hassite (tn, Site (kwargs. at)) && return tensors (tn; at= Site (kwargs. at))
171
+ hassite (tn, Site (kwargs. at; dual= true )) && return tensors (tn; at= Site (kwargs. at; dual= true ))
172
+ throw (ArgumentError (" Lane $kwargs .at not found" ))
173
+ end
170
174
171
175
"""
172
176
tensors(tn::AbstractAnsatz; bond)
@@ -375,7 +379,8 @@ Compute the expectation value of an observable on a [`AbstractAnsatz`](@ref) Ten
375
379
function expect (ψ:: AbstractAnsatz , observable; bra= adjoint (ψ))
376
380
@assert socket (ψ) == State () " ψ must be a state"
377
381
@assert socket (bra) == State (; dual= true ) " bra must be a dual state"
378
- contract (merge (ψ, observable, bra))
382
+
383
+ return expect (form (ψ), ψ, observable; bra)
379
384
end
380
385
381
386
function expect (ψ:: AbstractAnsatz , observables:: AbstractVecOrTuple ; bra= adjoint (ψ))
@@ -384,6 +389,50 @@ function expect(ψ::AbstractAnsatz, observables::AbstractVecOrTuple; bra=adjoint
384
389
end
385
390
end
386
391
392
+ function expect (:: NonCanonical , ψ:: AbstractAnsatz , observable; bra= adjoint (ψ))
393
+ return contract (merge (ψ, observable, bra))
394
+ end
395
+
396
+ # TODO : Try to find a better way to do this
397
+ function expect (:: MixedCanonical , ψ:: AbstractAnsatz , observable; bra= adjoint (ψ))
398
+ return contract (merge (ψ, observable, bra))
399
+ end
400
+
401
+ function expect (:: Canonical , ψ:: Tenet.AbstractAnsatz , observable; bra= adjoint (ψ))
402
+ obs_sites = unique (id .(sites (observable)))
403
+
404
+ ket_Λ = []
405
+ bra_Λ = []
406
+ ket_tensors = []
407
+ bra_tensors = []
408
+ for i in obs_sites
409
+ replace! (observable, inds (observable; at= Site (i)) => Symbol (:input , i))
410
+ replace! (observable, inds (observable; at= Site (i; dual= true )) => Symbol (:output , i))
411
+ replace! (ψ, inds (ψ; at= Site (i)) => Symbol (:input , i))
412
+ replace! (bra, inds (bra; at= Site (i; dual= true )) => Symbol (:output , i))
413
+
414
+ replace! (bra, inds (bra; bond= (Lane (i), Lane (i + 1 ))) => inds (ψ; bond= (Lane (i), Lane (i + 1 ))))
415
+ replace! (bra, inds (bra; bond= (Lane (i - 1 ), Lane (i))) => inds (ψ; bond= (Lane (i - 1 ), Lane (i))))
416
+
417
+ push! (ket_Λ, tensors (ψ; bond= (Lane (i - 1 ), Lane (i))))
418
+ push! (bra_Λ, tensors (bra; bond= (Lane (i - 1 ), Lane (i))))
419
+
420
+ push! (ket_tensors, tensors (ψ; at= Site (i)))
421
+ push! (bra_tensors, tensors (bra; at= Site (i; dual= true )))
422
+ end
423
+
424
+ push! (ket_Λ, tensors (ψ; bond= (Lane (obs_sites[end ]), Lane (obs_sites[end ] + 1 ))))
425
+ push! (bra_Λ, tensors (bra; bond= (Lane (obs_sites[end ]), Lane (obs_sites[end ] + 1 ))))
426
+
427
+ t = contract (
428
+ contract (ket_Λ... , ket_tensors... ; dims= []),
429
+ contract (bra_Λ... , bra_tensors... ; dims= []),
430
+ tensors (Quantum (observable))[1 ],
431
+ )
432
+
433
+ return t
434
+ end
435
+
387
436
"""
388
437
evolve!(ψ::AbstractAnsatz, gate; threshold = nothing, maxdim = nothing, normalize = false)
389
438
@@ -485,10 +534,10 @@ function simple_update_2site!(::NonCanonical, ψ::AbstractAnsatz, gate; kwargs..
485
534
gate = copy (gate)
486
535
487
536
# contract involved sites
488
- bond = (sitel, siter ) = extrema (lanes (gate))
537
+ bond = (lanel, laner ) = extrema (lanes (gate))
489
538
vind = inds (ψ; bond)
490
- linds = filter (!= (vind), inds (tensors (ψ; at= sitel )))
491
- rinds = filter (!= (vind), inds (tensors (ψ; at= siter )))
539
+ linds = filter (!= (vind), inds (tensors (ψ; at= lanel )))
540
+ rinds = filter (!= (vind), inds (tensors (ψ; at= laner )))
492
541
contract! (ψ; bond)
493
542
494
543
# TODO replace for `merge!` when #243 is fixed
@@ -519,20 +568,20 @@ end
519
568
# TODO remove `normalize` argument?
520
569
function simple_update_2site! (:: Canonical , ψ:: AbstractAnsatz , gate; threshold, maxdim, normalize= false , canonize= true )
521
570
# Contract the exterior Λ tensors
522
- sitel, siter = extrema (lanes (gate))
523
- (0 < id (sitel ) < nlanes (ψ) || 0 < id (siter ) < nlanes (ψ)) ||
571
+ lanel, laner = extrema (lanes (gate))
572
+ (0 < id (lanel ) < nlanes (ψ) || 0 < id (laner ) < nlanes (ψ)) ||
524
573
throw (ArgumentError (" The sites in the bond must be between 1 and $(nlanes (ψ)) " ))
525
574
526
- Λᵢ₋₁ = id (sitel ) == 1 ? nothing : tensors (ψ; between = (Lane (id (sitel ) - 1 ), sitel ))
527
- Λᵢ₊₁ = id (sitel ) == nsites (ψ) - 1 ? nothing : tensors (ψ; between = (siter , Lane (id (siter ) + 1 )))
575
+ Λᵢ₋₁ = id (lanel ) == 1 ? nothing : tensors (ψ; bond = (Lane (id (lanel ) - 1 ), lanel ))
576
+ Λᵢ₊₁ = id (lanel ) == nsites (ψ) - 1 ? nothing : tensors (ψ; bond = (laner , Lane (id (laner ) + 1 )))
528
577
529
- ! isnothing (Λᵢ₋₁) && contract ! (ψ; between = (Lane (id (sitel ) - 1 ), sitel ), direction = :right , delete_Λ= false )
530
- ! isnothing (Λᵢ₊₁) && contract ! (ψ; between = (siter , Lane (id (siter ) + 1 )), direction = :left , delete_Λ= false )
578
+ ! isnothing (Λᵢ₋₁) && absorb ! (ψ; bond = (Lane (id (lanel ) - 1 ), lanel ), dir = :right , delete_Λ= false )
579
+ ! isnothing (Λᵢ₊₁) && absorb ! (ψ; bond = (laner , Lane (id (laner ) + 1 )), dir = :left , delete_Λ= false )
531
580
532
581
simple_update_2site! (NonCanonical (), ψ, gate; threshold, maxdim, normalize= false , canonize= false )
533
582
534
583
# contract the updated tensors with the inverse of Λᵢ and Λᵢ₊₂, to get the new Γ tensors
535
- U, Vt = tensors (ψ; at= sitel ), tensors (ψ; at= siter )
584
+ U, Vt = tensors (ψ; at= lanel ), tensors (ψ; at= laner )
536
585
Γᵢ₋₁ = if isnothing (Λᵢ₋₁)
537
586
U
538
587
else
@@ -545,13 +594,13 @@ function simple_update_2site!(::Canonical, ψ::AbstractAnsatz, gate; threshold,
545
594
end
546
595
547
596
# Update the tensors in the tensor network
548
- replace! (ψ, tensors (ψ; at= sitel ) => Γᵢ₋₁)
549
- replace! (ψ, tensors (ψ; at= siter ) => Γᵢ)
597
+ replace! (ψ, tensors (ψ; at= lanel ) => Γᵢ₋₁)
598
+ replace! (ψ, tensors (ψ; at= laner ) => Γᵢ)
550
599
551
600
if canonize
552
601
canonize! (ψ; normalize)
553
602
else
554
- normalize && normalize! (ψ, collect ((sitel, siter )))
603
+ normalize && normalize! (ψ, collect ((lanel, laner )))
555
604
end
556
605
557
606
return ψ
0 commit comments