@@ -103,11 +103,11 @@ def construct_matrix_v2(ham: List[List[float]], dtype: Any = tf.complex128) -> T
103
103
104
104
def construct_matrix_v3 (ham : List [List [float ]], dtype : Any = tf .complex128 ) -> Tensor :
105
105
from ..quantum import PauliStringSum2COO
106
- from ..cons import backend
107
106
108
107
sparsem = PauliStringSum2COO ([h [1 :] for h in ham ], [h [0 ] for h in ham ]) # type: ignore
109
- densem = backend .to_dense (sparsem )
110
- return tf .cast (densem , dtype )
108
+ return sparsem
109
+ # densem = backend.to_dense(sparsem)
110
+ # return tf.cast(densem, dtype)
111
111
112
112
113
113
def vqe_energy (c : Circuit , h : List [List [float ]], reuse : bool = True ) -> Tensor :
@@ -130,15 +130,9 @@ def vqe_energy(c: Circuit, h: List[List[float]], reuse: bool = True) -> Tensor:
130
130
131
131
132
132
def vqe_energy_shortcut (c : Circuit , h : Tensor ) -> Tensor :
133
- w = c .wavefunction ()
134
- e = (tf .math .conj (tf .reshape (w , [1 , - 1 ])) @ h @ tf .reshape (w , [- 1 , 1 ]))[0 , 0 ]
135
- return e
133
+ from ..templates .measurements import operator_expectation
136
134
137
-
138
- def vqe_energy_shortcut_sparse (c : Circuit , h : Tensor ) -> Tensor :
139
- from ..templates .measurememts import sparse_expectation
140
-
141
- return sparse_expectation (c , h )
135
+ return operator_expectation (c , h )
142
136
143
137
144
138
class Linear (tf .keras .layers .Layer ): # type: ignore
@@ -232,24 +226,20 @@ def __init__(
232
226
circuit_params = {"epochs" : 2 , "stddev" : 0.1 }
233
227
self .epochs = circuit_params .get ("epochs" , 2 )
234
228
self .circuit_stddev = circuit_params .get ("stddev" , 0.1 )
229
+ self .channel = circuit_params .get ("channel" , 2 )
235
230
236
231
self .circuit_variable = tf .Variable (
237
232
tf .random .normal (
238
233
mean = 0.0 ,
239
234
stddev = self .circuit_stddev ,
240
- shape = [2 * self .epochs , self .n ],
235
+ shape = [self .epochs , self .n , self . channel ],
241
236
dtype = tf .float64 ,
242
237
)
243
238
)
244
239
self .circuit = self .create_circuit (** circuit_params )
245
240
self .base = tf .constant (list (product (* [[0 , 1 ] for _ in range (n )])))
246
241
self .hamiltonian = hamiltonian
247
242
self .shortcut = shortcut
248
- if shortcut :
249
- hmatrix = construct_matrix_v3 (self .hamiltonian )
250
- self .hop = hmatrix
251
- # self.hop = tf.constant(hmatrix, dtype=tf.complex128)
252
- # self.hop = G.any(hmatrix.copy().reshape([2 for _ in range(2 * n)]))
253
243
254
244
def assign (
255
245
self , c : Optional [List [Tensor ]] = None , q : Optional [Tensor ] = None
@@ -369,6 +359,8 @@ def create_circuit(
369
359
) -> Callable [[Tensor ], Tensor ]:
370
360
if choose == "hea" :
371
361
return self .create_hea_circuit (** kws )
362
+ if choose == "hea2" :
363
+ return self .create_hea2_circuit (** kws )
372
364
if choose == "hn" :
373
365
return self .create_hn_circuit (** kws )
374
366
raise ValueError ("no such choose option: %s" % choose )
@@ -395,15 +387,39 @@ def circuit(a: Tensor) -> Tensor:
395
387
c .X (i ) # type: ignore
396
388
for epoch in range (epochs ):
397
389
for i in range (self .n ):
398
- c .rx (i , theta = tf . cast ( a [ 2 * epoch , i ], dtype = dtype ) ) # type: ignore
390
+ c .rx (i , theta = a [ epoch , i , 0 ] ) # type: ignore
399
391
for i in range (self .n ):
400
- c .rz (i , theta = tf . cast ( a [ 2 * epoch + 1 , i ], dtype = dtype ) ) # type: ignore
392
+ c .rz (i , theta = a [ epoch , i , 1 ] ) # type: ignore
401
393
for i in range (self .n - 1 ):
402
394
c .cnot (i , (i + 1 )) # type: ignore
403
395
return c
404
396
405
397
return circuit
406
398
399
+ def create_hea2_circuit (
400
+ self , epochs : int = 2 , filled_qubit : Optional [List [int ]] = None , ** kws : Any
401
+ ) -> Callable [[Tensor ], Tensor ]:
402
+ if filled_qubit is None :
403
+ filled_qubit = [0 ]
404
+
405
+ def circuit (a : Tensor ) -> Tensor :
406
+ c = Circuit (self .n )
407
+ if filled_qubit :
408
+ for i in filled_qubit :
409
+ c .X (i ) # type: ignore
410
+ for epoch in range (epochs ):
411
+ for i in range (self .n ):
412
+ c .rx (i , theta = a [epoch , i , 0 ]) # type: ignore
413
+ for i in range (self .n ):
414
+ c .rz (i , theta = a [epoch , i , 1 ]) # type: ignore
415
+ for i in range (self .n ):
416
+ c .rx (i , theta = a [epoch , i , 2 ]) # type: ignore
417
+ for i in range (self .n - 1 ):
418
+ c .exp1 (i , (i + 1 ), theta = a [epoch , i , 3 ], unitary = G ._zz_matrix ) # type: ignore
419
+ return c
420
+
421
+ return circuit
422
+
407
423
@tf .function # type: ignore
408
424
def evaluation (self , cv : Tensor ) -> Tuple [Tensor , Tensor , Tensor ]:
409
425
"""
@@ -426,7 +442,7 @@ def evaluation(self, cv: Tensor) -> Tuple[Tensor, Tensor, Tensor]:
426
442
if not self .shortcut :
427
443
loss = tf .math .real (vqe_energy (c2 , self .hamiltonian ))
428
444
else :
429
- loss = tf .math .real (vqe_energy_shortcut (c2 , self .hop ))
445
+ loss = tf .math .real (vqe_energy_shortcut (c2 , self .hamiltonian ))
430
446
grad = tape .gradient (loss , [cv , self .model .variables ])
431
447
for i , gr in enumerate (grad ):
432
448
if gr is None :
@@ -452,7 +468,7 @@ def plain_evaluation(self, cv: Tensor) -> Tensor:
452
468
if not self .shortcut :
453
469
loss = tf .math .real (vqe_energy (c , self .hamiltonian ))
454
470
else :
455
- loss = tf .math .real (vqe_energy_shortcut (c , self .hop ))
471
+ loss = tf .math .real (vqe_energy_shortcut (c , self .hamiltonian ))
456
472
grad = tape .gradient (loss , cv )
457
473
return loss , grad
458
474
@@ -558,7 +574,7 @@ def multi_training(
558
574
tf .random .normal (
559
575
mean = 0.0 ,
560
576
stddev = self .circuit_stddev ,
561
- shape = [2 * self .epochs , self .n ],
577
+ shape = [self .epochs , self .n , self . channel ],
562
578
dtype = tf .float64 ,
563
579
)
564
580
)
0 commit comments