From 11ce038dd675e727432532a16c28d9250613c05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=ABDeploy=20tket=20C++=20documentation=C2=BB=20github?= =?UTF-8?q?=20action?= Date: Fri, 17 Jan 2025 08:42:20 +0000 Subject: [PATCH] Add generated tket C++ documentation. --- .../api/BasicOptimisation_8cpp_source.html | 931 +++++++++--------- .../api/BasicOptimisation_8hpp_source.html | 10 +- docs/tket/api/Decomposition_8cpp_source.html | 2 +- docs/tket/api/PassGenerators_8cpp_source.html | 2 +- docs/tket/api/PassLibrary_8cpp_source.html | 4 +- .../api/ThreeQubitSquash_8cpp_source.html | 2 +- .../tket/api/namespacetket_1_1Transforms.html | 12 +- 7 files changed, 483 insertions(+), 480 deletions(-) diff --git a/docs/tket/api/BasicOptimisation_8cpp_source.html b/docs/tket/api/BasicOptimisation_8cpp_source.html index 20b15739e0..470d447d7d 100644 --- a/docs/tket/api/BasicOptimisation_8cpp_source.html +++ b/docs/tket/api/BasicOptimisation_8cpp_source.html @@ -363,472 +363,474 @@
267 circ.get_next_edge(*v, current_edge_on_qb[q]);
268 }
269 }
-
270 } else if (circ.n_in_edges_of_type(*v, EdgeType::Quantum) == 2) {
-
271 // Check for 2qb gate
-
272 Qubit q0 = v_to_qb.at({*v, 0});
-
273 Qubit q1 = v_to_qb.at({*v, 1});
-
274 int i0 = current_interaction[q0];
-
275 int i1 = current_interaction[q1];
-
276 // If they are already interacting, extend it
-
277 if (i0 != -1 && i0 == i1) {
-
278 i_vec[i0].count++;
-
279 i_vec[i0].vertices.insert(*v);
-
280 current_edge_on_qb[q0] =
-
281 circ.get_next_edge(*v, current_edge_on_qb[q0]);
-
282 current_edge_on_qb[q1] =
-
283 circ.get_next_edge(*v, current_edge_on_qb[q1]);
-
284 } else {
-
285 // End any other interactions on q0
-
286 if (i0 != -1) {
-
287 if (i_vec[i0].count >= 2) {
-
288 // Replace subcircuit
-
289 success |= replace_two_qubit_interaction(
-
290 circ, i_vec[i0], current_edge_on_qb, bin, target_2qb_gate,
-
291 cx_fidelity, allow_swaps);
-
292 }
-
293 current_interaction[i_vec[i0].q0] = -1;
-
294 current_interaction[i_vec[i0].q1] = -1;
-
295 }
-
296 // End any other interactions on q1
-
297 if (i1 != -1) {
-
298 if (i_vec[i1].count >= 2) {
-
299 // Replace subcircuit
-
300
-
301 success |= replace_two_qubit_interaction(
-
302 circ, i_vec[i1], current_edge_on_qb, bin, target_2qb_gate,
-
303 cx_fidelity, allow_swaps);
-
304 }
-
305 current_interaction[i_vec[i1].q0] = -1;
-
306 current_interaction[i_vec[i1].q1] = -1;
-
307 }
-
308 // Add new interaction
-
309 Interaction new_i(q0, q1);
-
310 new_i.e0 = current_edge_on_qb[q0];
-
311 new_i.e1 = current_edge_on_qb[q1];
-
312 new_i.count = 1;
-
313 new_i.vertices = {*v};
-
314 current_interaction[q0] = i_vec.size();
-
315 current_interaction[q1] = i_vec.size();
-
316 i_vec.push_back(new_i);
-
317 current_edge_on_qb[q0] =
-
318 circ.get_next_edge(*v, current_edge_on_qb[q0]);
-
319 current_edge_on_qb[q1] =
-
320 circ.get_next_edge(*v, current_edge_on_qb[q1]);
-
321 }
-
322 } else {
-
323 // We don't care about single-qubit vertices, so just update edges
-
324 // and add vertices if interactions exist
-
325 for (port_t i = 0; i < circ.n_in_edges(*v); i++) {
-
326 Qubit q = v_to_qb.at({*v, i});
-
327 current_edge_on_qb[q] =
-
328 circ.get_next_edge(*v, current_edge_on_qb[q]);
-
329 int inter = current_interaction[q];
-
330 if (inter != -1) {
-
331 i_vec[inter].vertices.insert(*v);
-
332 }
-
333 }
-
334 }
-
335 }
-
336 }
-
337 circ.remove_vertices(
-
338 bin, Circuit::GraphRewiring::No, Circuit::VertexDeletion::Yes);
-
339
-
340 if (success) {
-
341 squash_1qb_to_tk1().apply(circ);
-
342 }
-
343 return success;
-
344 });
-
345}
+
270 } else if (
+
271 is_gate_type(type) &&
+
272 circ.n_in_edges_of_type(*v, EdgeType::Quantum) == 2) {
+
273 // Check for 2qb gate
+
274 Qubit q0 = v_to_qb.at({*v, 0});
+
275 Qubit q1 = v_to_qb.at({*v, 1});
+
276 int i0 = current_interaction[q0];
+
277 int i1 = current_interaction[q1];
+
278 // If they are already interacting, extend it
+
279 if (i0 != -1 && i0 == i1) {
+
280 i_vec[i0].count++;
+
281 i_vec[i0].vertices.insert(*v);
+
282 current_edge_on_qb[q0] =
+
283 circ.get_next_edge(*v, current_edge_on_qb[q0]);
+
284 current_edge_on_qb[q1] =
+
285 circ.get_next_edge(*v, current_edge_on_qb[q1]);
+
286 } else {
+
287 // End any other interactions on q0
+
288 if (i0 != -1) {
+
289 if (i_vec[i0].count >= 2) {
+
290 // Replace subcircuit
+
291 success |= replace_two_qubit_interaction(
+
292 circ, i_vec[i0], current_edge_on_qb, bin, target_2qb_gate,
+
293 cx_fidelity, allow_swaps);
+
294 }
+
295 current_interaction[i_vec[i0].q0] = -1;
+
296 current_interaction[i_vec[i0].q1] = -1;
+
297 }
+
298 // End any other interactions on q1
+
299 if (i1 != -1) {
+
300 if (i_vec[i1].count >= 2) {
+
301 // Replace subcircuit
+
302
+
303 success |= replace_two_qubit_interaction(
+
304 circ, i_vec[i1], current_edge_on_qb, bin, target_2qb_gate,
+
305 cx_fidelity, allow_swaps);
+
306 }
+
307 current_interaction[i_vec[i1].q0] = -1;
+
308 current_interaction[i_vec[i1].q1] = -1;
+
309 }
+
310 // Add new interaction
+
311 Interaction new_i(q0, q1);
+
312 new_i.e0 = current_edge_on_qb[q0];
+
313 new_i.e1 = current_edge_on_qb[q1];
+
314 new_i.count = 1;
+
315 new_i.vertices = {*v};
+
316 current_interaction[q0] = i_vec.size();
+
317 current_interaction[q1] = i_vec.size();
+
318 i_vec.push_back(new_i);
+
319 current_edge_on_qb[q0] =
+
320 circ.get_next_edge(*v, current_edge_on_qb[q0]);
+
321 current_edge_on_qb[q1] =
+
322 circ.get_next_edge(*v, current_edge_on_qb[q1]);
+
323 }
+
324 } else {
+
325 // We don't care about single-qubit vertices, so just update edges
+
326 // and add vertices if interactions exist
+
327 for (port_t i = 0; i < circ.n_in_edges(*v); i++) {
+
328 Qubit q = v_to_qb.at({*v, i});
+
329 current_edge_on_qb[q] =
+
330 circ.get_next_edge(*v, current_edge_on_qb[q]);
+
331 int inter = current_interaction[q];
+
332 if (inter != -1) {
+
333 i_vec[inter].vertices.insert(*v);
+
334 }
+
335 }
+
336 }
+
337 }
+
338 }
+
339 circ.remove_vertices(
+
340 bin, Circuit::GraphRewiring::No, Circuit::VertexDeletion::Yes);
+
341
+
342 if (success) {
+
343 squash_1qb_to_tk1().apply(circ);
+
344 }
+
345 return success;
+
346 });
+
347}
-
346
-
347// Given a 'SWAP_chain', finds edge in chain (or qubit wire) with best fidelity
-
348// and rewires the associated single qubit vertex in to it
-
349static bool find_edge_rewire_vertex(
-
350 Circuit &circ,
-
351 std::pair<std::vector<std::pair<Edge, double>>, Vertex> &entry) {
-
352 std::vector<std::pair<Edge, double>> candidates = entry.first;
-
353 std::pair<Edge, double> best_pair = candidates[0];
-
354 bool do_rewire = false; // prevents rewiring if current edge is best edge
-
355 // (causes many issues...)
-
356 for (unsigned i = 1; i < candidates.size(); i++) { // find best edge
-
357 if (candidates[i].second > best_pair.second) {
-
358 best_pair = candidates[i];
-
359 do_rewire = true;
-
360 }
-
361 }
-
362 if (do_rewire) {
-
363 // rewire in to best edge
-
364 circ.remove_vertex(
-
365 entry.second, Circuit::GraphRewiring::Yes, Circuit::VertexDeletion::No);
-
366 circ.rewire(entry.second, {best_pair.first}, {EdgeType::Quantum});
-
367 }
-
368 return do_rewire;
-
369}
-
370
-
371// Given a SWAP vertex, which has some predecessor SWAP vertex, find the
-
372// 'SWAP_chain' this predecessor SWAP vertex is in and add to it
-
373static void extend_SWAP_chain(
-
374 std::list<std::pair<std::vector<std::pair<Edge, double>>, Vertex>>
-
375 &swap_chains,
-
376 Edge entry_edge, Node entry_node, const Edge &match, const Circuit &circ,
-
377 const DeviceCharacterisation &characterisation) {
-
378 for (auto it = swap_chains.begin(); it != swap_chains.end(); ++it) {
-
379 if ((*it).first.back().first == match) {
-
380 // extend chain, adding a new pair of edge and double to the end
-
381 (*it).first.push_back(
-
382 {entry_edge,
-
383 1.0 - characterisation.get_error(
-
384 entry_node, circ.get_OpType_from_Vertex((*it).second))});
-
385 return;
-
386 }
-
387 }
-
388}
-
389
-
390// Finds sequences of adjacent SWAP gates, with a predecessor Single Qubit
-
391// Vertex. The error rate of the required Single Qubit Vertex is stored for each
-
392// of the PhysicalQubits the LogicalQubit passes through Once 'SWAP_chains' are
-
393// found throughout the whole circuit, predecessor Single Qubit Vertices are
-
394// rewired into the edge with best error rate
-
395static bool find_rewire_sq(
-
396 Circuit &circ, const DeviceCharacterisation &characterisation) {
-
397 std::list<std::pair<std::vector<std::pair<Edge, double>>, Vertex>>
-
398 swap_chains;
-
399 for (auto it = circ.begin(); it != circ.end(); ++it) {
-
400 if (it->get_op_ptr()->get_type() == OpType::SWAP) {
-
401 // find SWAP, if either predecessor is a single qubit unitary
-
402 // find resulting swap chain...
-
403 Vertex swap_vert = it.get_vertex();
-
404 unit_vector_t qubits = it->get_args();
-
405 node_vector_t nodes = {qubits.begin(), qubits.end()};
-
406 VertexVec pred_verts = circ.get_predecessors(swap_vert);
-
407 EdgeVec pred_edges = circ.get_in_edges(swap_vert);
-
408 EdgeVec post_edges = circ.get_all_out_edges(swap_vert);
-
409 for (unsigned i = 0; i < pred_verts.size(); i++) {
-
410 OpType optype = circ.get_OpType_from_Vertex(
-
411 pred_verts[i]); // OPT IS PREDECESSOR OPTYPE
-
412 if (circ.detect_singleq_unitary_op(pred_verts[i])) {
-
413 // wire has single qubit unitary->add a new swap chain
-
414 std::vector<std::pair<Edge, double>> swap_chain = {
-
415 {pred_edges[i],
-
416 1.0 - characterisation.get_error(nodes[i], optype)},
-
417 {post_edges[1 - i],
-
418 1.0 - characterisation.get_error(nodes[1 - i], optype)}};
-
419 swap_chains.push_back(std::make_pair(swap_chain, pred_verts[i]));
-
420 } else if (optype == OpType::SWAP) { // wire has swap->assume this swap
-
421 // already in chain, find chain
-
422 Edge pre_edge = pred_edges[i];
-
423 extend_SWAP_chain(
-
424 swap_chains, post_edges[1 - i], nodes[1 - i], pre_edge, circ,
-
425 characterisation);
-
426 }
-
427 }
-
428 }
-
429 }
-
430 // having produced swap chains, now find best qubit for gate to act on and
-
431 // implement
-
432 bool success = false;
-
433 while (!swap_chains.empty()) {
-
434 if (find_edge_rewire_vertex(circ, (*swap_chains.begin())) == true) {
-
435 success = true;
-
436 }
-
437 swap_chains.erase(swap_chains.begin());
-
438 }
-
439 return success;
-
440}
-
441
-
442static Transform commute_SQ_gates_through_SWAPS_helper(
-
443 const DeviceCharacterisation &characterisation) {
-
444 return Transform([characterisation](Circuit &circ) {
-
445 bool success = false;
-
446 while (find_rewire_sq(circ, characterisation)) {
-
447 success = true;
-
448 }
-
449 return success;
-
450 });
-
451}
-
452
-
- -
454 return commute_SQ_gates_through_SWAPS_helper(
-
455 DeviceCharacterisation(node_errors));
-
456}
+
348
+
349// Given a 'SWAP_chain', finds edge in chain (or qubit wire) with best fidelity
+
350// and rewires the associated single qubit vertex in to it
+
351static bool find_edge_rewire_vertex(
+
352 Circuit &circ,
+
353 std::pair<std::vector<std::pair<Edge, double>>, Vertex> &entry) {
+
354 std::vector<std::pair<Edge, double>> candidates = entry.first;
+
355 std::pair<Edge, double> best_pair = candidates[0];
+
356 bool do_rewire = false; // prevents rewiring if current edge is best edge
+
357 // (causes many issues...)
+
358 for (unsigned i = 1; i < candidates.size(); i++) { // find best edge
+
359 if (candidates[i].second > best_pair.second) {
+
360 best_pair = candidates[i];
+
361 do_rewire = true;
+
362 }
+
363 }
+
364 if (do_rewire) {
+
365 // rewire in to best edge
+
366 circ.remove_vertex(
+ +
368 circ.rewire(entry.second, {best_pair.first}, {EdgeType::Quantum});
+
369 }
+
370 return do_rewire;
+
371}
+
372
+
373// Given a SWAP vertex, which has some predecessor SWAP vertex, find the
+
374// 'SWAP_chain' this predecessor SWAP vertex is in and add to it
+
375static void extend_SWAP_chain(
+
376 std::list<std::pair<std::vector<std::pair<Edge, double>>, Vertex>>
+
377 &swap_chains,
+
378 Edge entry_edge, Node entry_node, const Edge &match, const Circuit &circ,
+
379 const DeviceCharacterisation &characterisation) {
+
380 for (auto it = swap_chains.begin(); it != swap_chains.end(); ++it) {
+
381 if ((*it).first.back().first == match) {
+
382 // extend chain, adding a new pair of edge and double to the end
+
383 (*it).first.push_back(
+
384 {entry_edge,
+
385 1.0 - characterisation.get_error(
+
386 entry_node, circ.get_OpType_from_Vertex((*it).second))});
+
387 return;
+
388 }
+
389 }
+
390}
+
391
+
392// Finds sequences of adjacent SWAP gates, with a predecessor Single Qubit
+
393// Vertex. The error rate of the required Single Qubit Vertex is stored for each
+
394// of the PhysicalQubits the LogicalQubit passes through Once 'SWAP_chains' are
+
395// found throughout the whole circuit, predecessor Single Qubit Vertices are
+
396// rewired into the edge with best error rate
+
397static bool find_rewire_sq(
+
398 Circuit &circ, const DeviceCharacterisation &characterisation) {
+
399 std::list<std::pair<std::vector<std::pair<Edge, double>>, Vertex>>
+
400 swap_chains;
+
401 for (auto it = circ.begin(); it != circ.end(); ++it) {
+
402 if (it->get_op_ptr()->get_type() == OpType::SWAP) {
+
403 // find SWAP, if either predecessor is a single qubit unitary
+
404 // find resulting swap chain...
+
405 Vertex swap_vert = it.get_vertex();
+
406 unit_vector_t qubits = it->get_args();
+
407 node_vector_t nodes = {qubits.begin(), qubits.end()};
+
408 VertexVec pred_verts = circ.get_predecessors(swap_vert);
+
409 EdgeVec pred_edges = circ.get_in_edges(swap_vert);
+
410 EdgeVec post_edges = circ.get_all_out_edges(swap_vert);
+
411 for (unsigned i = 0; i < pred_verts.size(); i++) {
+
412 OpType optype = circ.get_OpType_from_Vertex(
+
413 pred_verts[i]); // OPT IS PREDECESSOR OPTYPE
+
414 if (circ.detect_singleq_unitary_op(pred_verts[i])) {
+
415 // wire has single qubit unitary->add a new swap chain
+
416 std::vector<std::pair<Edge, double>> swap_chain = {
+
417 {pred_edges[i],
+
418 1.0 - characterisation.get_error(nodes[i], optype)},
+
419 {post_edges[1 - i],
+
420 1.0 - characterisation.get_error(nodes[1 - i], optype)}};
+
421 swap_chains.push_back(std::make_pair(swap_chain, pred_verts[i]));
+
422 } else if (optype == OpType::SWAP) { // wire has swap->assume this swap
+
423 // already in chain, find chain
+
424 Edge pre_edge = pred_edges[i];
+
425 extend_SWAP_chain(
+
426 swap_chains, post_edges[1 - i], nodes[1 - i], pre_edge, circ,
+
427 characterisation);
+
428 }
+
429 }
+
430 }
+
431 }
+
432 // having produced swap chains, now find best qubit for gate to act on and
+
433 // implement
+
434 bool success = false;
+
435 while (!swap_chains.empty()) {
+
436 if (find_edge_rewire_vertex(circ, (*swap_chains.begin())) == true) {
+
437 success = true;
+
438 }
+
439 swap_chains.erase(swap_chains.begin());
+
440 }
+
441 return success;
+
442}
+
443
+
444static Transform commute_SQ_gates_through_SWAPS_helper(
+
445 const DeviceCharacterisation &characterisation) {
+
446 return Transform([characterisation](Circuit &circ) {
+
447 bool success = false;
+
448 while (find_rewire_sq(circ, characterisation)) {
+
449 success = true;
+
450 }
+
451 return success;
+
452 });
+
453}
+
454
+
+ +
456 return commute_SQ_gates_through_SWAPS_helper(
+
457 DeviceCharacterisation(node_errors));
+
458}
-
- -
458 return commute_SQ_gates_through_SWAPS_helper(
-
459 DeviceCharacterisation(node_errors));
-
460}
+
+ +
460 return commute_SQ_gates_through_SWAPS_helper(
+
461 DeviceCharacterisation(node_errors));
+
462}
-
461
-
- -
463 return Transform([](Circuit &circ) {
-
464 bool success = false;
-
465 VertexSet all_bins;
-
466
-
467 // Start by squashing Rz gates
-
468 success |= squash_1qb_to_pqp(OpType::Rz, OpType::Rx).apply(circ);
-
469
-
470 // Loop through all NPhasedX gates
-
471 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
-
472 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
-
473 if (op->get_type() == OpType::NPhasedX) {
-
474 // gather surrounding Rz gates
-
475 unsigned arity = op->n_qubits();
-
476 std::vector<Expr> in_rz(arity);
-
477 std::vector<Expr> out_rz(arity);
- - -
480 TKET_ASSERT(in_edges.size() == arity);
-
481 TKET_ASSERT(out_edges.size() == arity);
-
482 for (unsigned i = 0; i < arity; ++i) {
-
483 Vertex in_v = circ.source(in_edges[i]);
-
484 Op_ptr in_op = circ.get_Op_ptr_from_Vertex(in_v);
-
485 Vertex out_v = circ.target(out_edges[i]);
-
486 Op_ptr out_op = circ.get_Op_ptr_from_Vertex(out_v);
-
487
-
488 if (in_op->get_type() == OpType::Rz) {
-
489 in_rz[i] = -in_op->get_params().at(0);
-
490 } else {
-
491 in_rz[i] = 0.;
-
492 }
-
493 if (out_op->get_type() == OpType::Rz) {
-
494 out_rz[i] = out_op->get_params().at(0);
-
495 } else {
-
496 out_rz[i] = 0.;
-
497 }
-
498 }
-
499
-
500 // Find out which Rz angle is most popular.
-
501 // Note that we only compare expr[i] with expr[j] when j < i. This means
-
502 // that only the largest i from a set of equivalent exprs will have the
-
503 // right occurence count, but that is good enough.
-
504 std::vector<Expr> all_rz = in_rz;
-
505 all_rz.insert(all_rz.end(), out_rz.begin(), out_rz.end());
-
506 std::vector<unsigned> occurences_count(2 * arity);
-
507 for (unsigned i = 0; i < 2 * arity; ++i) {
-
508 unsigned cnt = 0;
-
509 for (unsigned j = 0; j < i; ++j) {
-
510 if (equiv_expr(all_rz[i], all_rz[j], 4)) {
-
511 ++cnt;
-
512 }
-
513 }
-
514 occurences_count[i] = cnt;
-
515 }
-
516 unsigned max_i =
-
517 std::max_element(occurences_count.begin(), occurences_count.end()) -
-
518 occurences_count.begin();
-
519 Expr absorb_rz = all_rz[max_i];
-
520
-
521 if (!equiv_0(absorb_rz, 4)) {
-
522 success = true;
-
523
-
524 // Subtract absorb_rz in NPhasedX
-
525 std::vector<Expr> new_params = op->get_params();
-
526 TKET_ASSERT(new_params.size() == 2);
-
527 new_params[1] += absorb_rz;
-
528 circ.dag[v] = get_op_ptr(OpType::NPhasedX, new_params, arity);
-
529
-
530 // Finally, adjust +-absorb_rz in Rz everywhere around
-
531 for (unsigned i = 0; i < arity; ++i) {
-
532 Vertex in_v = circ.source(in_edges[i]);
-
533 Op_ptr in_op = circ.get_Op_ptr_from_Vertex(in_v);
-
534 Vertex out_v = circ.target(out_edges[i]);
-
535 Op_ptr out_op = circ.get_Op_ptr_from_Vertex(out_v);
-
536
-
537 Expr angle;
-
538 Edge in_e, out_e;
-
539 VertexSet bin;
-
540 if (in_op->get_type() == OpType::Rz) {
-
541 angle = in_op->get_params().at(0) + absorb_rz;
-
542 out_e = in_edges[i];
-
543 in_e = circ.get_last_edge(in_v, out_e);
-
544 bin = {in_v};
-
545 } else {
-
546 angle = absorb_rz;
-
547 out_e = in_edges[i];
-
548 in_e = out_e;
-
549 bin = {};
-
550 }
-
551 Subcircuit sub{{in_e}, {out_e}, bin};
-
552 Circuit c(1);
-
553 if (!equiv_0(angle, 4)) {
-
554 c.add_op<unsigned>(OpType::Rz, angle, {0});
-
555 }
- -
557 all_bins.insert(bin.begin(), bin.end());
-
558
-
559 if (out_op->get_type() == OpType::Rz) {
-
560 angle = out_op->get_params().at(0) - absorb_rz;
-
561 in_e = out_edges[i];
-
562 out_e = circ.get_next_edge(out_v, in_e);
-
563 bin = {out_v};
-
564 } else {
-
565 angle = -absorb_rz;
-
566 in_e = out_edges[i];
-
567 out_e = in_e;
-
568 bin = {};
-
569 }
-
570 sub = Subcircuit{{in_e}, {out_e}, bin};
-
571 c = Circuit(1);
-
572 if (!equiv_0(angle, 4)) {
-
573 c.add_op<unsigned>(OpType::Rz, angle, {0});
-
574 }
- -
576 all_bins.insert(bin.begin(), bin.end());
-
577 }
-
578 }
-
579 }
-
580 }
-
581 circ.remove_vertices(
- -
583
-
584 return success;
-
585 });
-
586}
+
463
+
+ +
465 return Transform([](Circuit &circ) {
+
466 bool success = false;
+
467 VertexSet all_bins;
+
468
+
469 // Start by squashing Rz gates
+
470 success |= squash_1qb_to_pqp(OpType::Rz, OpType::Rx).apply(circ);
+
471
+
472 // Loop through all NPhasedX gates
+
473 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
+
474 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
+
475 if (op->get_type() == OpType::NPhasedX) {
+
476 // gather surrounding Rz gates
+
477 unsigned arity = op->n_qubits();
+
478 std::vector<Expr> in_rz(arity);
+
479 std::vector<Expr> out_rz(arity);
+ + +
482 TKET_ASSERT(in_edges.size() == arity);
+
483 TKET_ASSERT(out_edges.size() == arity);
+
484 for (unsigned i = 0; i < arity; ++i) {
+
485 Vertex in_v = circ.source(in_edges[i]);
+
486 Op_ptr in_op = circ.get_Op_ptr_from_Vertex(in_v);
+
487 Vertex out_v = circ.target(out_edges[i]);
+
488 Op_ptr out_op = circ.get_Op_ptr_from_Vertex(out_v);
+
489
+
490 if (in_op->get_type() == OpType::Rz) {
+
491 in_rz[i] = -in_op->get_params().at(0);
+
492 } else {
+
493 in_rz[i] = 0.;
+
494 }
+
495 if (out_op->get_type() == OpType::Rz) {
+
496 out_rz[i] = out_op->get_params().at(0);
+
497 } else {
+
498 out_rz[i] = 0.;
+
499 }
+
500 }
+
501
+
502 // Find out which Rz angle is most popular.
+
503 // Note that we only compare expr[i] with expr[j] when j < i. This means
+
504 // that only the largest i from a set of equivalent exprs will have the
+
505 // right occurence count, but that is good enough.
+
506 std::vector<Expr> all_rz = in_rz;
+
507 all_rz.insert(all_rz.end(), out_rz.begin(), out_rz.end());
+
508 std::vector<unsigned> occurences_count(2 * arity);
+
509 for (unsigned i = 0; i < 2 * arity; ++i) {
+
510 unsigned cnt = 0;
+
511 for (unsigned j = 0; j < i; ++j) {
+
512 if (equiv_expr(all_rz[i], all_rz[j], 4)) {
+
513 ++cnt;
+
514 }
+
515 }
+
516 occurences_count[i] = cnt;
+
517 }
+
518 unsigned max_i =
+
519 std::max_element(occurences_count.begin(), occurences_count.end()) -
+
520 occurences_count.begin();
+
521 Expr absorb_rz = all_rz[max_i];
+
522
+
523 if (!equiv_0(absorb_rz, 4)) {
+
524 success = true;
+
525
+
526 // Subtract absorb_rz in NPhasedX
+
527 std::vector<Expr> new_params = op->get_params();
+
528 TKET_ASSERT(new_params.size() == 2);
+
529 new_params[1] += absorb_rz;
+
530 circ.dag[v] = get_op_ptr(OpType::NPhasedX, new_params, arity);
+
531
+
532 // Finally, adjust +-absorb_rz in Rz everywhere around
+
533 for (unsigned i = 0; i < arity; ++i) {
+
534 Vertex in_v = circ.source(in_edges[i]);
+
535 Op_ptr in_op = circ.get_Op_ptr_from_Vertex(in_v);
+
536 Vertex out_v = circ.target(out_edges[i]);
+
537 Op_ptr out_op = circ.get_Op_ptr_from_Vertex(out_v);
+
538
+
539 Expr angle;
+
540 Edge in_e, out_e;
+
541 VertexSet bin;
+
542 if (in_op->get_type() == OpType::Rz) {
+
543 angle = in_op->get_params().at(0) + absorb_rz;
+
544 out_e = in_edges[i];
+
545 in_e = circ.get_last_edge(in_v, out_e);
+
546 bin = {in_v};
+
547 } else {
+
548 angle = absorb_rz;
+
549 out_e = in_edges[i];
+
550 in_e = out_e;
+
551 bin = {};
+
552 }
+
553 Subcircuit sub{{in_e}, {out_e}, bin};
+
554 Circuit c(1);
+
555 if (!equiv_0(angle, 4)) {
+
556 c.add_op<unsigned>(OpType::Rz, angle, {0});
+
557 }
+ +
559 all_bins.insert(bin.begin(), bin.end());
+
560
+
561 if (out_op->get_type() == OpType::Rz) {
+
562 angle = out_op->get_params().at(0) - absorb_rz;
+
563 in_e = out_edges[i];
+
564 out_e = circ.get_next_edge(out_v, in_e);
+
565 bin = {out_v};
+
566 } else {
+
567 angle = -absorb_rz;
+
568 in_e = out_edges[i];
+
569 out_e = in_e;
+
570 bin = {};
+
571 }
+
572 sub = Subcircuit{{in_e}, {out_e}, bin};
+
573 c = Circuit(1);
+
574 if (!equiv_0(angle, 4)) {
+
575 c.add_op<unsigned>(OpType::Rz, angle, {0});
+
576 }
+ +
578 all_bins.insert(bin.begin(), bin.end());
+
579 }
+
580 }
+
581 }
+
582 }
+
583 circ.remove_vertices(
+ +
585
+
586 return success;
+
587 });
+
588}
-
587
-
- -
589 // basic optimisation, replace ZZPhase with two Rz(1)
-
590 return Transform([](Circuit &circ) {
-
591 bool success = false;
-
592 VertexSet bin;
-
593
-
594 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
-
595 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
-
596 if (op->get_type() == OpType::ZZPhase) {
-
597 auto params = op->get_params();
-
598 TKET_ASSERT(params.size() == 1);
-
599 // evaluate
-
600 std::optional<double> param = eval_expr(params[0]);
-
601 if (param.has_value() && std::abs(param.value()) == 1.0) {
-
602 success = true;
-
603 // basic optimisation, replace ZZPhase with two Rz(1)
-
604 Circuit replacement(2);
-
605 replacement.add_op<unsigned>(OpType::Rz, 1.0, {0});
-
606 replacement.add_op<unsigned>(OpType::Rz, 1.0, {1});
-
607 circ.substitute(replacement, v, Circuit::VertexDeletion::No);
-
608 bin.insert(v);
-
609 }
-
610 }
-
611 }
-
612 circ.remove_vertices(
- -
614 return success;
-
615 });
-
616}
+
589
+
+ +
591 // basic optimisation, replace ZZPhase with two Rz(1)
+
592 return Transform([](Circuit &circ) {
+
593 bool success = false;
+
594 VertexSet bin;
+
595
+
596 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
+
597 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
+
598 if (op->get_type() == OpType::ZZPhase) {
+
599 auto params = op->get_params();
+
600 TKET_ASSERT(params.size() == 1);
+
601 // evaluate
+
602 std::optional<double> param = eval_expr(params[0]);
+
603 if (param.has_value() && std::abs(param.value()) == 1.0) {
+
604 success = true;
+
605 // basic optimisation, replace ZZPhase with two Rz(1)
+
606 Circuit replacement(2);
+
607 replacement.add_op<unsigned>(OpType::Rz, 1.0, {0});
+
608 replacement.add_op<unsigned>(OpType::Rz, 1.0, {1});
+
609 circ.substitute(replacement, v, Circuit::VertexDeletion::No);
+
610 bin.insert(v);
+
611 }
+
612 }
+
613 }
+
614 circ.remove_vertices(
+ +
616 return success;
+
617 });
+
618}
-
617
-
- -
619 return Transform([](Circuit &circ) {
-
620 bool success = false;
-
621 VertexSet bin;
-
622
-
623 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
-
624 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
-
625 bool conditional = op->get_type() == OpType::Conditional;
-
626 if (conditional) {
-
627 const Conditional &cond = static_cast<const Conditional &>(*op);
-
628 op = cond.get_op();
-
629 }
-
630 if (op->get_type() == OpType::TK2) {
-
631 auto params = op->get_params();
-
632 TKET_ASSERT(params.size() == 3);
-
633 if (!in_weyl_chamber({params[0], params[1], params[2]})) {
-
634 success = true;
-
635 if (conditional) {
- - -
638 params[0], params[1], params[2]),
- -
640 } else {
-
641 circ.substitute(
- -
643 params[0], params[1], params[2]),
- -
645 }
-
646 bin.insert(v);
-
647 }
-
648 }
-
649 }
-
650
-
651 circ.remove_vertices(
- -
653
-
654 return success;
-
655 });
-
656}
+
619
+
+ +
621 return Transform([](Circuit &circ) {
+
622 bool success = false;
+
623 VertexSet bin;
+
624
+
625 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
+
626 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
+
627 bool conditional = op->get_type() == OpType::Conditional;
+
628 if (conditional) {
+
629 const Conditional &cond = static_cast<const Conditional &>(*op);
+
630 op = cond.get_op();
+
631 }
+
632 if (op->get_type() == OpType::TK2) {
+
633 auto params = op->get_params();
+
634 TKET_ASSERT(params.size() == 3);
+
635 if (!in_weyl_chamber({params[0], params[1], params[2]})) {
+
636 success = true;
+
637 if (conditional) {
+ + +
640 params[0], params[1], params[2]),
+ +
642 } else {
+
643 circ.substitute(
+ +
645 params[0], params[1], params[2]),
+ +
647 }
+
648 bin.insert(v);
+
649 }
+
650 }
+
651 }
+
652
+
653 circ.remove_vertices(
+ +
655
+
656 return success;
+
657 });
+
658}
-
657
-
-
658Transform round_angles(unsigned n, bool only_zeros) {
-
659 if (n >= 32) {
-
660 throw std::invalid_argument("Precision parameter must be less than 32.");
-
661 }
-
662 return Transform([n, only_zeros](Circuit &circ) {
-
663 bool changed = false;
-
664 VertexSet bin;
-
665 const unsigned pow2n = 1 << n;
-
666 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
-
667 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
-
668 bool conditional = op->get_type() == OpType::Conditional;
-
669 if (conditional) {
-
670 const Conditional &cond = static_cast<const Conditional &>(*op);
-
671 op = cond.get_op();
-
672 }
-
673 if (op->get_desc().is_gate()) {
-
674 std::vector<Expr> params = op->get_params();
-
675 if (!params.empty()) {
-
676 std::vector<Expr> new_params;
-
677 for (const Expr &e : params) {
-
678 std::optional<double> eval = eval_expr(e);
-
679 if (eval) {
-
680 if (only_zeros) {
-
681 new_params.push_back(
-
682 pow2n * std::abs(eval.value()) < 0.5 ? 0. : e);
-
683 } else {
-
684 new_params.push_back(nearbyint(pow2n * eval.value()) / pow2n);
-
685 }
-
686 } else {
-
687 new_params.push_back(e);
-
688 }
-
689 }
-
690 if (params != new_params) {
-
691 unsigned n_qb = op->n_qubits();
-
692 Circuit replacement(n_qb);
-
693 if (std::any_of(
-
694 new_params.begin(), new_params.end(),
-
695 [](const Expr &e) { return (e != 0.); })) {
-
696 std::vector<Qubit> args;
-
697 for (unsigned i = 0; i < n_qb; i++) {
-
698 args.push_back(Qubit(i));
-
699 }
-
700 replacement.add_op(op->get_type(), new_params, args);
-
701 }
-
702 if (conditional) {
- -
704 replacement, v, Circuit::VertexDeletion::No);
-
705 } else {
-
706 circ.substitute(replacement, v, Circuit::VertexDeletion::No);
-
707 }
-
708 bin.insert(v);
-
709 changed = true;
-
710 }
-
711 }
-
712 }
-
713 }
-
714
-
715 circ.remove_vertices(
- -
717
-
718 return changed;
-
719 });
-
720}
+
659
+
+
660Transform round_angles(unsigned n, bool only_zeros) {
+
661 if (n >= 32) {
+
662 throw std::invalid_argument("Precision parameter must be less than 32.");
+
663 }
+
664 return Transform([n, only_zeros](Circuit &circ) {
+
665 bool changed = false;
+
666 VertexSet bin;
+
667 const unsigned pow2n = 1 << n;
+
668 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
+
669 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
+
670 bool conditional = op->get_type() == OpType::Conditional;
+
671 if (conditional) {
+
672 const Conditional &cond = static_cast<const Conditional &>(*op);
+
673 op = cond.get_op();
+
674 }
+
675 if (op->get_desc().is_gate()) {
+
676 std::vector<Expr> params = op->get_params();
+
677 if (!params.empty()) {
+
678 std::vector<Expr> new_params;
+
679 for (const Expr &e : params) {
+
680 std::optional<double> eval = eval_expr(e);
+
681 if (eval) {
+
682 if (only_zeros) {
+
683 new_params.push_back(
+
684 pow2n * std::abs(eval.value()) < 0.5 ? 0. : e);
+
685 } else {
+
686 new_params.push_back(nearbyint(pow2n * eval.value()) / pow2n);
+
687 }
+
688 } else {
+
689 new_params.push_back(e);
+
690 }
+
691 }
+
692 if (params != new_params) {
+
693 unsigned n_qb = op->n_qubits();
+
694 Circuit replacement(n_qb);
+
695 if (std::any_of(
+
696 new_params.begin(), new_params.end(),
+
697 [](const Expr &e) { return (e != 0.); })) {
+
698 std::vector<Qubit> args;
+
699 for (unsigned i = 0; i < n_qb; i++) {
+
700 args.push_back(Qubit(i));
+
701 }
+
702 replacement.add_op(op->get_type(), new_params, args);
+
703 }
+
704 if (conditional) {
+ +
706 replacement, v, Circuit::VertexDeletion::No);
+
707 } else {
+
708 circ.substitute(replacement, v, Circuit::VertexDeletion::No);
+
709 }
+
710 bin.insert(v);
+
711 changed = true;
+
712 }
+
713 }
+
714 }
+
715 }
+
716
+
717 circ.remove_vertices(
+ +
719
+
720 return changed;
+
721 });
+
722}
-
721
-
722} // namespace tket::Transforms
+
723
+
724} // namespace tket::Transforms
@@ -884,14 +886,14 @@
Transform decompose_TK2(bool allow_swaps)
Transform commute_through_multis()
-
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
+
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
Transform decompose_multi_qubits_TK2()
Decomposes all multi-qubit unitary gates into TK2 and single-qubit gates.
-
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
+
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
Transform squash_1qb_to_pqp(const OpType &q, const OpType &p, bool strict)
general u_squash by converting any chains of p, q gates (p, q in {Rx,Ry,Rz}) to triples -p-q-p- or -q...
Transform two_qubit_squash(bool allow_swaps)
-
Transform commute_SQ_gates_through_SWAPS(const avg_node_errors_t &node_errors)
-
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
-
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
+
Transform commute_SQ_gates_through_SWAPS(const avg_node_errors_t &node_errors)
+
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
+
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
Transform squash_1qb_to_tk1()
Squash all single-qubit gates to TK1.
boost::graph_traits< DAG >::vertex_descriptor Vertex
Definition DAGDefs.hpp:73
OpType
Named operation types.
Definition OpType.hpp:29
@@ -912,6 +914,7 @@
bool is_initial_q_type(OpType optype)
Test for input or creation quantum "ops".
EdgeType
Type of a wire in a circuit or input to an op.
Definition EdgeType.hpp:23
@ Quantum
A wire carrying quantum information, corresponding to some allocated Qubit.
+
bool is_gate_type(OpType optype)
Test for elementary gates.
bool in_weyl_chamber(const std::array< Expr, 3 > &k)
Whether a triplet of TK2 angles are normalised.
std::pair< Vertex, port_t > VertPort
Definition DAGDefs.hpp:99
Eigen::Matrix4cd get_matrix_from_2qb_circ(const Circuit &circ)
Convert a two-qubit circuit to its corresponding matrix.
Definition CircUtils.cpp:63
diff --git a/docs/tket/api/BasicOptimisation_8hpp_source.html b/docs/tket/api/BasicOptimisation_8hpp_source.html index ff73c70983..fec4b44d0c 100644 --- a/docs/tket/api/BasicOptimisation_8hpp_source.html +++ b/docs/tket/api/BasicOptimisation_8hpp_source.html @@ -172,16 +172,16 @@
Transform remove_redundancies()
Transform commute_through_multis()
-
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
-
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
+
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
+
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
Transform squash_1qb_to_pqp(const OpType &q, const OpType &p, bool strict)
general u_squash by converting any chains of p, q gates (p, q in {Rx,Ry,Rz}) to triples -p-q-p- or -q...
Transform squash_1qb_to_Rz_PhasedX(bool always_squash_symbols)
Squash single qubit gates into PhasedX and Rz gates.
Transform two_qubit_squash(bool allow_swaps)
bool redundancy_removal(Circuit &circuit)
Transform squash_factory(const OpTypeSet &singleqs, const std::function< Circuit(const Expr &, const Expr &, const Expr &)> &tk1_replacement, bool always_squash_symbols)
-
Transform commute_SQ_gates_through_SWAPS(const avg_node_errors_t &node_errors)
-
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
-
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
+
Transform commute_SQ_gates_through_SWAPS(const avg_node_errors_t &node_errors)
+
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
+
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
Transform squash_1qb_to_tk1()
Squash all single-qubit gates to TK1.
Defines tket::DeviceCharacterisation, used in NoiseAwarePlacement and in commute_SQ_gates_through_SWA...
Definition Path.cpp:22
OpType
Named operation types.
Definition OpType.hpp:29
diff --git a/docs/tket/api/Decomposition_8cpp_source.html b/docs/tket/api/Decomposition_8cpp_source.html index 2b5b418e22..66ab9a23ae 100644 --- a/docs/tket/api/Decomposition_8cpp_source.html +++ b/docs/tket/api/Decomposition_8cpp_source.html @@ -2278,7 +2278,7 @@
Transform cnx_pairwise_decomposition()
Transform decompose_tk1_to_rzrx()
Transform decompose_ZY()
-
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
+
Transform absorb_Rz_NPhasedX()
Absorb Rz gates into NPhasedX where possible.
Transform decompose_BRIDGE_to_CX()
Transform decompose_ZX_to_cliffords()
Transform decompose_MolmerSorensen()
diff --git a/docs/tket/api/PassGenerators_8cpp_source.html b/docs/tket/api/PassGenerators_8cpp_source.html index 8adaf14cac..8889aae96e 100644 --- a/docs/tket/api/PassGenerators_8cpp_source.html +++ b/docs/tket/api/PassGenerators_8cpp_source.html @@ -1476,7 +1476,7 @@
CreateAllQubits
Automatically create all qubits in zero state when simplifying?
-
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
+
Transform round_angles(unsigned n, bool only_zeros)
Generate a transform that rounds all angles to the nearest .
Transform squash_1qb_to_pqp(const OpType &q, const OpType &p, bool strict)
general u_squash by converting any chains of p, q gates (p, q in {Rx,Ry,Rz}) to triples -p-q-p- or -q...
Transform squash_1qb_to_Rz_PhasedX(bool always_squash_symbols)
Squash single qubit gates into PhasedX and Rz gates.
Transform special_UCC_synthesis(PauliSynthStrat strat, CXConfigType cx_config)
diff --git a/docs/tket/api/PassLibrary_8cpp_source.html b/docs/tket/api/PassLibrary_8cpp_source.html index 1a06d8f56c..4c70826b66 100644 --- a/docs/tket/api/PassLibrary_8cpp_source.html +++ b/docs/tket/api/PassLibrary_8cpp_source.html @@ -715,7 +715,7 @@
Transform commute_through_multis()
Transform decompose_single_qubits_TK1()
Decomposes all single-qubit unitary gates into TK1 gates.
Transform decompose_multi_qubits_CX()
Decomposes all multi-qubit unitary gates into CX and single-qubit gates.
-
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
+
Transform ZZPhase_to_Rz()
Converts any ZZPhase with angle in (-1, 1) to two pi Rz gates.
Transform remove_discarded_ops()
Remove all operations that have no OpType::Output or OpType::ClOutput in their causal future.
Transform decomp_arbitrary_controlled_gates()
Transform delay_measures(bool allow_partial)
Commute all measurement gates to the end of the circuit.
@@ -727,7 +727,7 @@
Transform decomp_boxes(const std::unordered_set< OpType > &excluded_types, const std::unordered_set< std::string > &excluded_opgroups)
Recursively replaces all boxes by their decomposition using Box::to_circuit Expects: any gateset.
Transform cnx_pairwise_decomposition()
Transform decompose_BRIDGE_to_CX()
-
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
+
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
Transform squash_1qb_to_tk1()
Squash all single-qubit gates to TK1.
Transform simplify_measured()
Commute classical maps through measurements.
Defines tket::DeviceCharacterisation, used in NoiseAwarePlacement and in commute_SQ_gates_through_SWA...
Definition Path.cpp:22
diff --git a/docs/tket/api/ThreeQubitSquash_8cpp_source.html b/docs/tket/api/ThreeQubitSquash_8cpp_source.html index 79403986fd..d446fbf8d3 100644 --- a/docs/tket/api/ThreeQubitSquash_8cpp_source.html +++ b/docs/tket/api/ThreeQubitSquash_8cpp_source.html @@ -505,7 +505,7 @@
Transform three_qubit_squash(OpType target_2qb_gate)
Squash sequences of 3-qubit instructions into a canonical form.
Transform clifford_simp(bool allow_swaps)
std::unique_ptr< QInteraction > iptr
-
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
+
Transform normalise_TK2()
Normalises all TK2 gates so that NormalisedTK2Predicate is satisfied.
Transform squash_1qb_to_tk1()
Squash all single-qubit gates to TK1.
Defines tket::DeviceCharacterisation, used in NoiseAwarePlacement and in commute_SQ_gates_through_SWA...
Definition Path.cpp:22
std::set< Edge > EdgeSet
Definition DAGDefs.hpp:95
diff --git a/docs/tket/api/namespacetket_1_1Transforms.html b/docs/tket/api/namespacetket_1_1Transforms.html index 23a39373a3..2937cd4455 100644 --- a/docs/tket/api/namespacetket_1_1Transforms.html +++ b/docs/tket/api/namespacetket_1_1Transforms.html @@ -572,7 +572,7 @@

Definition at line 462 of file BasicOptimisation.cpp.

+

Definition at line 464 of file BasicOptimisation.cpp.

@@ -793,7 +793,7 @@

-

Definition at line 453 of file BasicOptimisation.cpp.

+

Definition at line 455 of file BasicOptimisation.cpp.

@@ -813,7 +813,7 @@

-

Definition at line 457 of file BasicOptimisation.cpp.

+

Definition at line 459 of file BasicOptimisation.cpp.

@@ -1756,7 +1756,7 @@

NormalisedTK2Predicate is satisfied.

-

Definition at line 618 of file BasicOptimisation.cpp.

+

Definition at line 620 of file BasicOptimisation.cpp.

@@ -2289,7 +2289,7 @@

Precondition
n < 32
Returns
Transform to perform rounding
-

Definition at line 658 of file BasicOptimisation.cpp.

+

Definition at line 660 of file BasicOptimisation.cpp.

@@ -2821,7 +2821,7 @@

Definition at line 588 of file BasicOptimisation.cpp.

+

Definition at line 590 of file BasicOptimisation.cpp.