Source code for qrisp.qtypes.quantum_string

"""
********************************************************************************
* Copyright (c) 2025 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************
"""

import numpy as np

from qrisp.core.quantum_array import QuantumArray
from qrisp.qtypes.quantum_char import QuantumChar

nisq_init_quantum_char = QuantumChar(name="nisq_q_char")
init_quantum_char = QuantumChar(nisq_char=False, name="q_char")


[docs] class QuantumString(QuantumArray): """ The QuantumString is the quantum equivalent of a string. It is implemented as a :ref:`QuantumArray` of :ref:`QuantumChars <QuantumChar>`. >>> from qrisp import QuantumString >>> q_str = QuantumString(size = len("hello world")) >>> q_str[:] = "hello world" >>> print(q_str) {'hello world': 1.0} It is also possible to have a QuantumString containing non-nisq chars >>> q_str_nn = QuantumString(size = len("hello world"), nisq_char = False) >>> q_str_nn[:] = "hello world" >>> print(q_str_nn) {'hello world': 1.0} This requires however considerably more qubits >>> print(len(q_str.qs.qubits)) 55 >>> print(len(q_str_nn.qs.qubits)) 88 Similar to its parent class, the size of a QuantumString does not have to be specified at creation >>> q_str = QuantumString() >>> q_str[:] = "hello world" >>> print(q_str) {'hello world': 1.0} **Concatenation** QuantumStrings provide a number of methods to concatenate: >>> q_str_0 = QuantumString() >>> q_str_1 = QuantumString() >>> q_str_2 = QuantumString() >>> q_str_0[:] = "hello" >>> q_str_1 += " " >>> q_str_2[:] = "world" >>> q_str_3 = q_str_1 + q_str_2 >>> q_str_0 += q_str_3 >>> print(q_str_0) {'hello world': 1.0} Note that these QuantumStrings share memory - i.e. if we modify a QuantumChar in one of them, this will potentially affect the others: >>> from qrisp import h >>> h(q_str_2[0][0]) >>> print(q_str_0) {'hello world': 0.5, 'hello xorld': 0.5} """ def __init__(self, size, qs=None, nisq_char=True): if nisq_char: qtype = nisq_init_quantum_char else: qtype = init_quantum_char QuantumArray.__init__(self, qtype=qtype, shape=size, qs=qs) def get_measurement(self, **kwargs): mes_result = QuantumArray.get_measurement(self, **kwargs) return_dic = {} for k, v in mes_result.items(): return_dic["".join(list(k))] = v return return_dic def decoder(self, code_int): res_array = QuantumArray.decoder(self, code_int) res_str = "" for i in range(len(res_array)): res_str += res_array[i] return res_str def encode(self, encoding_str): encoding_array = np.array(list(encoding_str), dtype="object") QuantumArray.encode(self, encoding_array) def __setitem__(self, key, value): if isinstance(key, int): QuantumArray.__setitem__(self, key, value) return QuantumArray.__setitem__(self, key, [ch for ch in value]) @classmethod def quantize_string(cls, string): res = QuantumString(len(string)) res[:] = string return res def __add__(self, other): return self.concatenate(other) def __iadd__(self, other): if isinstance(other, QuantumString): return self + other elif isinstance(other, str): return self + QuantumString.quantize_string(other) else: raise Exception(f"Don't know how to concatenate with type {type(other)}")