Source code for pennylane.qchem.vibrational.taylor_ham
# Copyright 2018-2024 Xanadu Quantum Technologies Inc.# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at# http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""The functions related to the construction of the Taylor form Hamiltonian."""importitertoolsimportnumpyasnpfrompennylane.boseimportBoseSentence,BoseWord,binary_mapping,unary_mapping# pylint: disable=import-outside-topleveldef_import_sklearn():"""Import sklearn."""try:importsklearnexceptImportErrorasError:raiseImportError("This feature requires sklearn. It can be installed with: pip install scikit-learn.")fromErrorreturnsklearndef_remove_harmonic(freqs,onemode_pes):"""Removes the harmonic part from the PES. Args: freqs (list(float)): the harmonic frequencies in atomic units onemode_pes (TensorLike[float]): one mode PES Returns: tuple: A tuple containing the following: - TensorLike[float] : anharmonic part of the PES - TensorLike[float] : harmonic part of the PES """nmodes,quad_order=np.shape(onemode_pes)grid,_=np.polynomial.hermite.hermgauss(quad_order)harmonic_pes=np.zeros((nmodes,quad_order))anh_pes=np.zeros((nmodes,quad_order))foriiinrange(nmodes):ho_const=freqs[ii]/2harmonic_pes[ii,:]=ho_const*(grid**2)anh_pes[ii,:]=onemode_pes[ii,:]-harmonic_pes[ii,:]returnanh_pes,harmonic_pesdef_fit_onebody(onemode_op,max_deg,min_deg=3):r"""Fits the one-mode operator to get one-body coefficients. Args: onemode_op (TensorLike[float]): one-mode operator max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: tuple (TensorLike[float], TensorLike[float]): - the one-body coefficients - the predicted one-body PES using fitted coefficients """_import_sklearn()fromsklearn.linear_modelimportLinearRegressionfromsklearn.preprocessingimportPolynomialFeaturesifmax_deg<min_deg:raiseValueError(f"Taylor expansion degree is {max_deg}<{min_deg}, please set max_deg greater than min_deg.")nmodes,quad_order=np.shape(onemode_op)grid,_=np.polynomial.hermite.hermgauss(quad_order)coeffs=np.zeros((nmodes,max_deg-min_deg+1))predicted_1D=np.zeros_like(onemode_op)fori1inrange(nmodes):poly1D=PolynomialFeatures(degree=(min_deg,max_deg),include_bias=False)poly1D_features=poly1D.fit_transform(grid.reshape(-1,1))poly1D_reg_model=LinearRegression()poly1D_reg_model.fit(poly1D_features,onemode_op[i1,:])coeffs[i1,:]=poly1D_reg_model.coef_predicted_1D[i1,:]=poly1D_reg_model.predict(poly1D_features)returncoeffs,predicted_1Ddef_twobody_degs(max_deg,min_deg=3):"""Finds the degree of fit for two-body coefficients. Args: max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: list(tuple): A list of tuples `(q1deg, q2deg)` where the sum of the two values is guaranteed to be between the maximum total degree and minimum degree. """fit_degs=[]forfeat_deginrange(min_deg,max_deg+1):max_deg=feat_deg-1fordeg_distinrange(1,max_deg+1):q1deg=max_deg-deg_dist+1q2deg=deg_distfit_degs.append((q1deg,q2deg))returnfit_degsdef_fit_twobody(twomode_op,max_deg,min_deg=3):r"""Fits the two-mode operator to get two-body coefficients. Args: twomode_op (TensorLike[float]): two-mode operator max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: tuple (TensorLike[float], TensorLike[float]): - the two-body coefficients - the predicted two-body PES using fitted coefficients """_import_sklearn()fromsklearn.linear_modelimportLinearRegressionnmodes,_,quad_order,_=np.shape(twomode_op)gauss_grid,_=np.polynomial.hermite.hermgauss(quad_order)ifmax_deg<min_deg:raiseValueError(f"Taylor expansion degree is {max_deg}<{min_deg}, please set max_deg greater than min_deg.")fit_degs=_twobody_degs(max_deg,min_deg)num_coeffs=len(fit_degs)coeffs=np.zeros((nmodes,nmodes,num_coeffs))predicted_2D=np.zeros_like(twomode_op)grid_2D=np.array(np.meshgrid(gauss_grid,gauss_grid))q1,q2=(grid.flatten()forgridingrid_2D)idx_2D=np.array(np.meshgrid(range(quad_order),range(quad_order)))idx1,idx2=(idx.flatten()foridxinidx_2D)num_2D=len(q1)features=np.zeros((num_2D,num_coeffs))fordeg_idx,(q1deg,q2deg)inenumerate(fit_degs):features[:,deg_idx]=(q1**q1deg)*(q2**q2deg)fori1inrange(nmodes):fori2inrange(i1):Y=twomode_op[i1,i2,idx1,idx2]poly2D_reg_model=LinearRegression()poly2D_reg_model.fit(features,Y)coeffs[i1,i2,:]=poly2D_reg_model.coef_predicted=poly2D_reg_model.predict(features)foridxinrange(num_2D):predicted_2D[i1,i2,idx1[idx],idx2[idx]]=predicted[idx]returncoeffs,predicted_2Ddef_generate_bin_occupations(max_occ,nbins):""" Generate all valid combinations of bin occupations for a given number of bins and a total maximum occupancy. Args: max_occ(int): the maximum total number of items to be distributed across bins nbins(int): the number of bins to distribute the items into Returns list(tuple): A list of tuples, where each tuple represents a valid combination of item counts for the bins. """combinations=list(itertools.product(range(max_occ+1),repeat=nbins))valid_combinations=[comboforcomboincombinationsifsum(combo)==max_occ]returnvalid_combinationsdef_threebody_degs(max_deg,min_deg=3):"""Finds the degree of fit for three-body coefficients. Args: max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: list(tuple): A list of tuples `(q1deg, q2deg, q3deg)` where the sum of the three values is guaranteed to be between the maximum total degree and minimum degree. """fit_degs=[]forfeat_deginrange(min_deg,max_deg+1):max_deg=feat_deg-3ifmax_deg<0:continuepossible_occupations=_generate_bin_occupations(max_deg,3)foroccinpossible_occupations:q1deg=1+occ[0]q2deg=1+occ[1]q3deg=1+occ[2]fit_degs.append((q1deg,q2deg,q3deg))returnfit_degsdef_fit_threebody(threemode_op,max_deg,min_deg=3):r"""Fits the three-mode operator to get three-body coefficients. Args: threemode_op (TensorLike[float]): threemode operator max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: tuple (TensorLike[float], TensorLike[float]): - the three-body coefficients - the predicted three-body PES using fitted coefficients """_import_sklearn()fromsklearn.linear_modelimportLinearRegressionnmodes,_,_,quad_order,_,_=np.shape(threemode_op)gauss_grid,_=np.polynomial.hermite.hermgauss(quad_order)ifmax_deg<min_deg:raiseValueError(f"Taylor expansion degree is {max_deg}<{min_deg}, please set max_deg greater than min_deg.")predicted_3D=np.zeros_like(threemode_op)fit_degs=_threebody_degs(max_deg)num_coeffs=len(fit_degs)coeffs=np.zeros((nmodes,nmodes,nmodes,num_coeffs))grid_3D=np.array(np.meshgrid(gauss_grid,gauss_grid,gauss_grid))q1,q2,q3=(grid.flatten()forgridingrid_3D)idx_3D=np.array(np.meshgrid(range(quad_order),range(quad_order),range(quad_order)))idx1,idx2,idx3=(idx.flatten()foridxinidx_3D)num_3D=len(q1)features=np.zeros((num_3D,num_coeffs))fordeg_idx,Qsinenumerate(fit_degs):q1deg,q2deg,q3deg=Qsfeatures[:,deg_idx]=q1**(q1deg)*q2**(q2deg)*q3**(q3deg)fori1inrange(nmodes):fori2inrange(i1):fori3inrange(i2):Y=threemode_op[i1,i2,i3,idx1,idx2,idx3]poly3D_reg_model=LinearRegression()poly3D_reg_model.fit(features,Y)coeffs[i1,i2,i3,:]=poly3D_reg_model.coef_predicted=poly3D_reg_model.predict(features)foridxinrange(num_3D):predicted_3D[i1,i2,i3,idx1[idx],idx2[idx],idx3[idx]]=predicted[idx]returncoeffs,predicted_3D
[docs]deftaylor_coeffs(pes,max_deg=4,min_deg=3):r"""Compute fitted coefficients for Taylor vibrational Hamiltonian. The coefficients are defined following Eq. 5 of `arXiv:1703.09313 <https://arxiv.org/abs/1703.09313>`_ as: .. math:: \Phi_{ijk} = \frac{k_{ijk}}{\sqrt{\omega_i \omega_j \omega_k}} \quad \text{and} \quad \Phi_{ijkl} = \frac{k_{ijkl}}{\sqrt{\omega_i \omega_j \omega_k \omega_l}}, where :math:`\Phi_{ijk}` and :math:`\Phi_{ijkl}` are the third- and fourth-order reduced force constants, respectively, defined in terms of the third- and fourth-order partial derivatives of the potential energy surface data. Args: pes (VibrationalPES): object containing the vibrational potential energy surface data max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: tuple(TensorLike[float]): the coefficients of the one-body, two-body and three-body terms **Example** >>> pes_onemode = np.array([[0.309, 0.115, 0.038, 0.008, 0.000, 0.006, 0.020, 0.041, 0.070]]) >>> pes_twomode = np.zeros((1, 1, 9, 9)) >>> dipole_onemode = np.zeros((1, 9, 3)) >>> gauss_weights = np.array([3.96e-05, 4.94e-03, 8.85e-02, ... 4.33e-01, 7.20e-01, 4.33e-01, ... 8.85e-02, 4.94e-03, 3.96e-05]) >>> grid = np.array([-3.19, -2.27, -1.47, -0.72, 0.0, 0.72, 1.47, 2.27, 3.19]) >>> pes_object = qml.qchem.VibrationalPES( ... freqs=np.array([0.025]), ... grid=grid, ... uloc=np.array([[1.0]]), ... gauss_weights=gauss_weights, ... pes_data=[pes_onemode, pes_twomode], ... dipole_data=[dipole_onemode], ... localized=True, ... dipole_level=1, ... ) >>> one, two = qml.qchem.taylor_coeffs(pes_object, 4, 2) >>> print(one) [[-0.00088528 -0.00361425 0.00068143]] """anh_pes,harmonic_pes=_remove_harmonic(pes.freqs,pes.pes_onemode)coeff_1D,predicted_1D=_fit_onebody(anh_pes,max_deg,min_deg=min_deg)predicted_1D+=harmonic_pescoeff_arr=[coeff_1D]predicted_arr=[predicted_1D]ifpes.pes_twomodeisnotNone:coeff_2D,predicted_2D=_fit_twobody(pes.pes_twomode,max_deg,min_deg=min_deg)coeff_arr.append(coeff_2D)predicted_arr.append(predicted_2D)ifpes.pes_threemodeisnotNone:coeff_3D,predicted_3D=_fit_threebody(pes.pes_threemode,max_deg,min_deg=min_deg)coeff_arr.append(coeff_3D)predicted_arr.append(predicted_3D)returncoeff_arr
[docs]deftaylor_dipole_coeffs(pes,max_deg=4,min_deg=1):r"""Compute fitted coefficients for the Taylor dipole operator. Args: pes (VibrationalPES): object containing the vibrational potential energy surface data max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial Returns: tuple: a tuple containing: - list(array(floats)): coefficients for x-displacements - list(array(floats)): coefficients for y-displacements - list(array(floats)): coefficients for z-displacements **Example** >>> freqs = np.array([0.01885397]) >>> grid, weights = np.polynomial.hermite.hermgauss(9) >>> pes_onebody = np.array([[0.05235573, 0.03093067, 0.01501878, 0.00420778, 0.0, ... 0.00584504, 0.02881817, 0.08483433, 0.22025702]]) >>> pes_twobody = None >>> dipole_onebody = np.array([[[-1.92201700e-16, 1.45397041e-16, -1.40451549e-01], ... [-1.51005108e-16, 9.53185441e-17, -1.03377032e-01], ... [-1.22793018e-16, 7.22781963e-17, -6.92825934e-02], ... [-1.96537436e-16, -5.86686504e-19, -3.52245369e-02], ... [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], ... [ 5.24758835e-17, -1.40650833e-16, 3.69955543e-02], ... [-4.52407941e-17, 1.38406311e-16, 7.60888733e-02], ... [-4.63820104e-16, 5.42928787e-17, 1.17726042e-01], ... [ 1.19224372e-16, 9.12491386e-17, 1.64013197e-01]]]) >>> vib_obj = qml.qchem.VibrationalPES( ... freqs=freqs, ... grid=grid, ... gauss_weights=weights, ... uloc=None, ... pes_data=[pes_onebody, pes_twobody], ... dipole_data=[dipole_onebody], ... localized=False ... ) >>> x, y, z = qml.qchem.taylor_dipole_coeffs(vib_obj, 4, 2) >>> print(z) [array([[ 1.64124324e-03, 5.39120159e-03, -4.80053702e-05]])] """coeffs_x_1D,predicted_x_1D=_fit_onebody(pes.dipole_onemode[:,:,0],max_deg,min_deg=min_deg)coeffs_x_arr=[coeffs_x_1D]predicted_x_arr=[predicted_x_1D]coeffs_y_1D,predicted_y_1D=_fit_onebody(pes.dipole_onemode[:,:,1],max_deg,min_deg=min_deg)coeffs_y_arr=[coeffs_y_1D]predicted_y_arr=[predicted_y_1D]coeffs_z_1D,predicted_z_1D=_fit_onebody(pes.dipole_onemode[:,:,2],max_deg,min_deg=min_deg)coeffs_z_arr=[coeffs_z_1D]predicted_z_arr=[predicted_z_1D]ifpes.dipole_twomodeisnotNone:coeffs_x_2D,predicted_x_2D=_fit_twobody(pes.dipole_twomode[:,:,:,:,0],max_deg,min_deg=min_deg)coeffs_x_arr.append(coeffs_x_2D)predicted_x_arr.append(predicted_x_2D)coeffs_y_2D,predicted_y_2D=_fit_twobody(pes.dipole_twomode[:,:,:,:,1],max_deg,min_deg=min_deg)coeffs_y_arr.append(coeffs_y_2D)predicted_y_arr.append(predicted_y_2D)coeffs_z_2D,predicted_z_2D=_fit_twobody(pes.dipole_twomode[:,:,:,:,2],max_deg,min_deg=min_deg)coeffs_z_arr.append(coeffs_z_2D)predicted_z_arr.append(predicted_z_2D)ifpes.dipole_threemodeisnotNone:coeffs_x_3D,predicted_x_3D=_fit_threebody(pes.dipole_threemode[:,:,:,:,:,:,0],max_deg,min_deg=min_deg)coeffs_x_arr.append(coeffs_x_3D)predicted_x_arr.append(predicted_x_3D)coeffs_y_3D,predicted_y_3D=_fit_threebody(pes.dipole_threemode[:,:,:,:,:,:,1],max_deg,min_deg=min_deg)coeffs_y_arr.append(coeffs_y_3D)predicted_y_arr.append(predicted_y_3D)coeffs_z_3D,predicted_z_3D=_fit_threebody(pes.dipole_threemode[:,:,:,:,:,:,2],max_deg,min_deg=min_deg)coeffs_z_arr.append(coeffs_z_3D)predicted_z_arr.append(predicted_z_3D)returncoeffs_x_arr,coeffs_y_arr,coeffs_z_arr
def_position_to_boson(index,op):"""Convert position operator `p` or `q` into respective bosonic operator. The conversion is described in `Eq. 6 and 7 <https://arxiv.org/pdf/1703.09313>`_. Args: index (int): the index of the operator op (str): the position operator, either ``"p"`` or ``"q"`` Returns: BoseSentence: bosonic form of the given position operator """factor=1j/np.sqrt(2)ifop=="p"else1/np.sqrt(2)bop=factor*BoseWord({(0,index):"-"})bdag=factor*BoseWord({(0,index):"+"})returnbdag-bopifop=="p"elsebdag+bopdef_taylor_anharmonic(taylor_coeffs_array,start_deg=2):"""Build anharmonic term of Taylor form bosonic observable from provided coefficients described in `Eq. 10 <https://arxiv.org/pdf/1703.09313>`_. Args: taylor_coeffs_array (list(float)): the coeffs of the Taylor expansion start_deg (int): the starting degree Returns: pennylane.bose.BoseSentence: anharmonic part of the Taylor hamiltonian for given coeffs """num_coups=len(taylor_coeffs_array)taylor_1D=taylor_coeffs_array[0]num_modes,num_1D_coeffs=np.shape(taylor_1D)taylor_deg=num_1D_coeffs+start_deg-1ordered_dict=BoseSentence({})# One-mode expansionformodeinrange(num_modes):bosonized_qm=_position_to_boson(mode,"q")fordeg_iinrange(start_deg,taylor_deg+1):coeff=taylor_1D[mode,deg_i-start_deg]qpow=bosonized_qm**deg_iordered_dict+=(coeff*qpow).normal_order()# Two-mode expansionifnum_coups>1:taylor_2D=taylor_coeffs_array[1]degs_2d=_twobody_degs(taylor_deg,min_deg=start_deg)form1inrange(num_modes):bosonized_qm1=_position_to_boson(m1,"q")form2inrange(m1):bosonized_qm2=_position_to_boson(m2,"q")fordeg_idx,Qsinenumerate(degs_2d):q1deg,q2deg=Qs[:2]coeff=taylor_2D[m1,m2,deg_idx]bosonized_qm1_pow=bosonized_qm1**q1degbosonized_qm2_pow=bosonized_qm2**q2degordered_dict+=(coeff*bosonized_qm1_pow*bosonized_qm2_pow).normal_order()# Three-mode expansionifnum_coups>2:degs_3d=_threebody_degs(taylor_deg,min_deg=start_deg)taylor_3D=taylor_coeffs_array[2]form1inrange(num_modes):bosonized_qm1=_position_to_boson(m1,"q")form2inrange(m1):bosonized_qm2=_position_to_boson(m2,"q")form3inrange(m2):bosonized_qm3=_position_to_boson(m3,"q")fordeg_idx,Qsinenumerate(degs_3d):q1deg,q2deg,q3deg=Qs[:3]coeff=taylor_3D[m1,m2,m3,deg_idx]bosonized_qm1_pow=bosonized_qm1**q1degbosonized_qm2_pow=bosonized_qm2**q2degbosonized_qm3_pow=bosonized_qm3**q3degordered_dict+=(coeff*bosonized_qm1_pow*bosonized_qm2_pow*bosonized_qm3_pow).normal_order()returnBoseSentence(ordered_dict).normal_order()def_taylor_kinetic(taylor_coeffs_array,freqs,is_local=True,uloc=None):"""Build kinetic term of Taylor form bosonic observable from provided coefficients Args: taylor_coeffs_array (list(float)): the coeffs of the Taylor expansion freqs (list(float)): the harmonic frequencies in atomic units is_local (bool): Flag whether the vibrational modes are localized. Default is ``True``. uloc (list(list(float))): localization matrix indicating the relationship between original and localized modes Returns: pennylane.bose.BoseSentence: kinetic term of the Taylor hamiltonian for given coeffs """taylor_1D=taylor_coeffs_array[0]num_modes,_=np.shape(taylor_1D)ifis_local:alphas_arr=np.einsum("ij,ik,j,k->jk",uloc,uloc,np.sqrt(freqs),np.sqrt(freqs))else:alphas_arr=np.zeros((num_modes,num_modes))forminrange(num_modes):alphas_arr[m,m]=freqs[m]kin_ham=BoseSentence({})form1inrange(num_modes):pm1=_position_to_boson(m1,"p")form2inrange(num_modes):pm2=_position_to_boson(m2,"p")kin_ham+=(0.5*alphas_arr[m1,m2])*(pm1*pm2).normal_order()returnkin_ham.normal_order()def_taylor_harmonic(taylor_coeffs_array,freqs):"""Build harmonic term of Taylor form bosonic observable from provided coefficients, see first term of `Eq. 4 and Eq. 7 <https://arxiv.org/pdf/1703.09313>`_. Args: taylor_coeffs_array (list(float)): the coeffs of the Taylor expansion freqs (list(float)): the harmonic frequencies in atomic units Returns: pennylane.bose.BoseSentence: harmonic term of the Taylor hamiltonian for given coeffs """taylor_1D=taylor_coeffs_array[0]num_modes,_=np.shape(taylor_1D)harm_pot=BoseSentence({})formodeinrange(num_modes):bosonized_qm2=(_position_to_boson(mode,"q")*_position_to_boson(mode,"q")).normal_order()harm_pot+=bosonized_qm2*freqs[mode]*0.5returnharm_pot.normal_order()
[docs]deftaylor_bosonic(coeffs,freqs,is_local=True,uloc=None):"""Return Taylor bosonic vibrational Hamiltonian. The construction of the Hamiltonian is based on Eqs. 4-7 of `arXiv:1703.09313 <https://arxiv.org/abs/1703.09313>`_. Args: coeffs (list(float)): the coefficients of the Hamiltonian freqs (list(float)): the harmonic frequencies in atomic units is_local (bool): Flag whether the vibrational modes are localized. Default is ``True``. uloc (list(list(float))): localization matrix indicating the relationship between original and localized modes Returns: pennylane.bose.BoseSentence: Taylor bosonic hamiltonian **Example** >>> one_mode = np.array([[-0.00088528, -0.00361425, 0.00068143]]) >>> two_mode = np.array([[[0., 0., 0., 0., 0., 0.]]]) >>> freqs = np.array([0.025]) >>> uloc = np.array([[1.0]]) >>> ham = qml.qchem.taylor_bosonic(coeffs=[one_mode, two_mode], freqs=freqs, uloc=uloc) >>> print(ham) -0.0012778303419517393 * b⁺(0) b⁺(0) b⁺(0) + -0.0038334910258552178 * b⁺(0) b⁺(0) b(0) + -0.0038334910258552178 * b⁺(0) + -0.0038334910258552178 * b⁺(0) b(0) b(0) + -0.0038334910258552178 * b(0) + -0.0012778303419517393 * b(0) b(0) b(0) + (0.0005795050000000001+0j) * b⁺(0) b⁺(0) + (0.026159009999999996+0j) * b⁺(0) b(0) + (0.012568432499999997+0j) * I + (0.0005795050000000001+0j) * b(0) b(0) + 0.00017035749999999995 * b⁺(0) b⁺(0) b⁺(0) b⁺(0) + 0.0006814299999999998 * b⁺(0) b⁺(0) b⁺(0) b(0) + 0.0010221449999999997 * b⁺(0) b⁺(0) b(0) b(0) + 0.0006814299999999998 * b⁺(0) b(0) b(0) b(0) + 0.00017035749999999995 * b(0) b(0) b(0) b(0) """ifis_local:start_deg=2else:start_deg=3harm_pot=_taylor_harmonic(coeffs,freqs)ham=_taylor_anharmonic(coeffs,start_deg)+harm_potkin_ham=_taylor_kinetic(coeffs,freqs,is_local,uloc)ham+=kin_hamreturnham.normal_order()
[docs]deftaylor_hamiltonian(pes,max_deg=4,min_deg=3,mapping="binary",n_states=2,wire_map=None,tol=1e-12):"""Return Taylor vibrational Hamiltonian. The construction of the Hamiltonian is based on Eqs. 4-7 of `arXiv:1703.09313 <https://arxiv.org/abs/1703.09313>`_. The Hamiltonian is then converted to a qubit operator with a selected ``mapping`` method. Args: pes (VibrationalPES): object containing the vibrational potential energy surface data max_deg (int): maximum degree of Taylor form polynomial min_deg (int): minimum degree of Taylor form polynomial mapping (str): Method used to map to qubit basis. Input values can be ``"binary"`` or ``"unary"``. Default is ``"binary"``. n_states(int): maximum number of allowed bosonic states wire_map (dict): A dictionary defining how to map the states of the Bose operator to qubit wires. If ``None``, integers used to label the bosonic states will be used as wire labels. Defaults to ``None``. tol (float): tolerance for discarding the imaginary part of the coefficients Returns: Operator: the Taylor Hamiltonian **Example** >>> pes_onemode = np.array([[0.309, 0.115, 0.038, 0.008, 0.000, 0.006, 0.020, 0.041, 0.070]]) >>> pes_twomode = np.zeros((1, 1, 9, 9)) >>> dipole_onemode = np.zeros((1, 9, 3)) >>> gauss_weights = np.array([3.96e-05, 4.94e-03, 8.85e-02, ... 4.33e-01, 7.20e-01, 4.33e-01, ... 8.85e-02, 4.94e-03, 3.96e-05]) >>> grid = np.array([-3.19, -2.27, -1.47, -0.72, 0.0, 0.72, 1.47, 2.27, 3.19]) >>> pes_object = qml.qchem.VibrationalPES( ... freqs=np.array([0.025]), ... grid=grid, ... uloc=np.array([[1.0]]), ... gauss_weights=gauss_weights, ... pes_data=[pes_onemode, pes_twomode], ... dipole_data=[dipole_onemode], ... localized=True, ... dipole_level=1, ... ) >>> qml.qchem.taylor_hamiltonian(pes_object, 4, 2) ( -0.003833496032473659 * X(0) + (0.0256479442871582+0j) * I(0) + (-0.013079509779221888+0j) * Z(0) ) """coeffs_arr=taylor_coeffs(pes,max_deg,min_deg)bose_op=taylor_bosonic(coeffs_arr,pes.freqs,is_local=pes.localized,uloc=pes.uloc)mapping=mapping.lower().strip()ifmapping=="binary":ham=binary_mapping(bose_operator=bose_op,n_states=n_states,wire_map=wire_map,tol=tol)elifmapping=="unary":ham=unary_mapping(bose_operator=bose_op,n_states=n_states,wire_map=wire_map,tol=tol)else:raiseValueError(f"Specified mapping {mapping}, is not found. Please use either 'binary' or 'unary' mapping.")returnham