pqcprep.psi_tools
Collection of functions relating to the phase function $\Psi$ to be evaluated by the QCNN.
1r""" 2Collection of functions relating to the phase function $\Psi$ to be evaluated by the QCNN. 3""" 4import numpy as np 5from .binary_tools import bin_to_dec, dec_to_bin 6 7def x_trans(x): 8 """ 9 Transform a scalar to match the frequency scaling used for the gravitational wave binary system inspiral 10 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 11 12 Arguments: 13 ---- 14 - **x** : *float* 15 16 Scalar to be transformed. 17 18 Returns: 19 ---- 20 - **x_t** : *float* 21 22 Transformed scalar. 23 24 """ 25 n = 6 26 nint = n 27 fmin=40. 28 fmax=168. 29 df = (fmax-fmin)/(2**n) 30 31 xmax = np.power(2,nint) - np.power(2,nint-n) 32 x = x/xmax 33 x = x*(fmax-fmin-df) 34 x = x + fmin 35 x_t =x 36 return x_t 37 38 39def x_trans_arr(n): 40 """ 41 42 Generate an array of frequency values according to the frequency scaling used for the gravitational wave binary system inspiral 43 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 44 45 Arguments: 46 ---- 47 - **n** : *int* 48 49 Controls array size: length of the array is `2**n`. 50 51 Returns: 52 ---- 53 - **x_arr** : *array_like* 54 55 Array of values. 56 57 """ 58 x_min = 40 59 x_max = 168 60 dx = (x_max-x_min)/(2**n) 61 x_arr = np.arange(x_min, x_max, dx) 62 63 return x_arr 64 65def psi_H(x): 66 r""" 67 The phase function $\Psi$ for the gravitational wave binary system inspiral 68 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 69 70 Arguments: 71 ---- 72 - **x** : *float* 73 74 $x$. 75 76 Returns: 77 ---- 78 - **out** : *float* 79 80 $\Psi(x)$. 81 82 """ 83 84 # gravitational wave features 85 n = 6 86 fmin=40. 87 fmax=168. 88 m1=(4.926e-6)*35 89 m2=(4.926e-6)*30. 90 beta=0. 91 sig=0. 92 Tfrac = 100. 93 df = (fmax-fmin)/(2**n) 94 T = 1./df 95 tc = T + (T/Tfrac) 96 DT = tc%T 97 Mt = m1 + m2 98 nu = (m1*m2)/Mt 99 eta = nu/Mt 100 Mc = Mt*eta**(3./5) 101 102 # transform x to frequency scale 103 x = x_trans(x) 104 105 # apply function 106 out = (((3./128))*((np.pi*Mc*x)**(-5./3))*( 1.+ (20./9)*((743./336)+(11./4)*eta)*(np.pi*Mt*x)**(2./3) -4.*(4.*np.pi - beta)*(np.pi*Mt*x) + 10.*((3058673./1016064) + (eta*5429./1008) + (617*(eta**2)/144) - sig)*(np.pi*Mt*x)**(4./3)) + 2.*np.pi*x*DT)/(2.*np.pi) 107 108 return out 109 110def psi(x, mode="psi"): 111 r""" 112 A wrapper for different phase functions. 113 114 Inputs are scaled via `x_trans()` in all cases. 115 116 Arguments: 117 --- 118 - **x** : *float* 119 120 $x$. 121 122 - **mode** : *str* 123 124 Options are `'psi'` (corresponding to `psi_H()`), `'linear'` (corresponding to `psi_linear()`), `'quadratic'` (corresponding to `psi_quadratic()`), 125 `'sin'` (corresponding to `psi_sine()`). Default is `'psi'`. 126 127 Returns: 128 ---- 129 - **out** : *float* 130 131 $\Psi(x)$ for the $\Psi$ selected via `mode`. 132 133 134 """ 135 if mode=="sine": 136 out = psi_sine(x) 137 elif mode=="quadratic": 138 out = psi_quadratic(x) 139 elif mode=="linear": 140 out = psi_linear(x) 141 elif mode=="psi": 142 out = psi_H(x) 143 else: 144 raise ValueError('Unrecognised phase function mode. Options are "psi", "linear", "quadratic", "sine".') 145 146 return out 147 148def psi_linear(x): 149 r""" 150 A simple linear phase function $\Psi$. 151 152 Arguments: 153 ---- 154 - **x** : *float* 155 156 $x$. 157 158 Returns: 159 ---- 160 - **out** : *float* 161 162 $\Psi(x) \sim x$. 163 164 """ 165 x = x_trans(x) 166 out= 0.5 + 0.01*x 167 168 return out 169 170def psi_quadratic(x): 171 r""" 172 A simple quadratic phase function $\Psi$. 173 174 Arguments: 175 ---- 176 - **x** : *float* 177 178 $x$. 179 180 Returns: 181 ---- 182 - **out** : *float* 183 184 $\Psi(x) \sim x^2$. 185 186 """ 187 x = x_trans(x) 188 out= 0.0001* x**2 189 190 return out 191 192def psi_sine(x): 193 r""" 194 A simple sinusoidal phase function $\Psi$. 195 196 Arguments: 197 ---- 198 - **x** : *float* 199 200 $x$. 201 202 Returns: 203 ---- 204 - **out** : *float* 205 206 $\Psi(x) \sim \sin x$. 207 208 """ 209 x = x_trans(x) 210 out = np.pi /2 *(1+ np.sin(x /4 )) 211 212 return out 213 214def get_phase_target(m, psi_mode, phase_reduce=True, mint=0): 215 r""" 216 217 Generate an array of phase function values taking into account rounding due to the limited 218 size of the target register. 219 220 The number of values in the array is determined for the same frequency scaling as in `x_trans()`. 221 222 Arguments: 223 --- 224 - **m** : *int* 225 226 Number of qubits in the target register. 227 228 - **psi_mode** : *str* 229 230 String specifying the phase function. Must be one of the options for the `mode` argument of `psi()`. 231 232 - **phase_reduce** : *boolean* 233 234 If True, phase function is reduced to the interval $[0, 2 \pi]$ before rounding. Default is True. 235 236 - **mint** : *int* 237 238 Number of integer qubits. Default is 0. 239 240 Returns: 241 --- 242 - **phase_rounded** : *array_like* 243 244 Array containing phase function values rounded to the precision 245 afforded by the target register size. 246 247 248 """ 249 250 # define x array 251 n = 6 252 x_min = 40 253 x_max = 168 254 dx = (x_max-x_min)/(2**n) 255 x_arr = np.arange(x_min, x_max, dx) 256 257 # calculate target output for phase 258 phase_target = psi(np.linspace(0, 2**n, len(x_arr)),mode=psi_mode) 259 260 # calculate target for phase taking into account rounding 261 if phase_reduce: 262 phase_reduced = np.modf(phase_target / (2* np.pi))[0] 263 phase_reduced_bin = [dec_to_bin(i,m, "unsigned mag", mint) for i in phase_reduced] 264 phase_reduced_dec = np.array([bin_to_dec(i,"unsigned mag", mint) for i in phase_reduced_bin]) 265 if phase_reduce: 266 phase_rounded = 2 * np.pi * phase_reduced_dec 267 268 return phase_rounded 269 270 271def A(x, mode="x76"): 272 r""" 273 A wrapper for different amplitude functions. 274 275 Arguments: 276 --- 277 - **x** : *float* 278 279 $x$. 280 281 - **mode** : *str* 282 283 Options are `'x76'` (corresponding to $A(x) \sim x^{-7/6}$), `'uniform'` (corresponding to $A(x) \sim 1$), and `'linear'` (corresponding to $A(x) \sim x$). 284 Default is `'x76'`. 285 286 Returns: 287 ---- 288 - **out** : *float* 289 290 $A(x)$ for the $A$ selected via `mode`. 291 292 293 """ 294 if mode=="x76": 295 out = x**(-7/6) 296 elif mode=="uniform": 297 out = 1 298 elif mode=="linear": 299 out= x 300 else: 301 raise ValueError('Unrecognised phase function mode. Options are "x76", "uniform", "linear".') 302 303 return out
8def x_trans(x): 9 """ 10 Transform a scalar to match the frequency scaling used for the gravitational wave binary system inspiral 11 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 12 13 Arguments: 14 ---- 15 - **x** : *float* 16 17 Scalar to be transformed. 18 19 Returns: 20 ---- 21 - **x_t** : *float* 22 23 Transformed scalar. 24 25 """ 26 n = 6 27 nint = n 28 fmin=40. 29 fmax=168. 30 df = (fmax-fmin)/(2**n) 31 32 xmax = np.power(2,nint) - np.power(2,nint-n) 33 x = x/xmax 34 x = x*(fmax-fmin-df) 35 x = x + fmin 36 x_t =x 37 return x_t
Transform a scalar to match the frequency scaling used for the gravitational wave binary system inspiral in Hayes 2023.
Arguments:
x : float
Scalar to be transformed.
Returns:
x_t : float
Transformed scalar.
40def x_trans_arr(n): 41 """ 42 43 Generate an array of frequency values according to the frequency scaling used for the gravitational wave binary system inspiral 44 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 45 46 Arguments: 47 ---- 48 - **n** : *int* 49 50 Controls array size: length of the array is `2**n`. 51 52 Returns: 53 ---- 54 - **x_arr** : *array_like* 55 56 Array of values. 57 58 """ 59 x_min = 40 60 x_max = 168 61 dx = (x_max-x_min)/(2**n) 62 x_arr = np.arange(x_min, x_max, dx) 63 64 return x_arr
Generate an array of frequency values according to the frequency scaling used for the gravitational wave binary system inspiral in Hayes 2023.
Arguments:
n : int
Controls array size: length of the array is
2**n.
Returns:
x_arr : array_like
Array of values.
66def psi_H(x): 67 r""" 68 The phase function $\Psi$ for the gravitational wave binary system inspiral 69 in [Hayes 2023](https://arxiv.org/pdf/2306.11073). 70 71 Arguments: 72 ---- 73 - **x** : *float* 74 75 $x$. 76 77 Returns: 78 ---- 79 - **out** : *float* 80 81 $\Psi(x)$. 82 83 """ 84 85 # gravitational wave features 86 n = 6 87 fmin=40. 88 fmax=168. 89 m1=(4.926e-6)*35 90 m2=(4.926e-6)*30. 91 beta=0. 92 sig=0. 93 Tfrac = 100. 94 df = (fmax-fmin)/(2**n) 95 T = 1./df 96 tc = T + (T/Tfrac) 97 DT = tc%T 98 Mt = m1 + m2 99 nu = (m1*m2)/Mt 100 eta = nu/Mt 101 Mc = Mt*eta**(3./5) 102 103 # transform x to frequency scale 104 x = x_trans(x) 105 106 # apply function 107 out = (((3./128))*((np.pi*Mc*x)**(-5./3))*( 1.+ (20./9)*((743./336)+(11./4)*eta)*(np.pi*Mt*x)**(2./3) -4.*(4.*np.pi - beta)*(np.pi*Mt*x) + 10.*((3058673./1016064) + (eta*5429./1008) + (617*(eta**2)/144) - sig)*(np.pi*Mt*x)**(4./3)) + 2.*np.pi*x*DT)/(2.*np.pi) 108 109 return out
The phase function $\Psi$ for the gravitational wave binary system inspiral in Hayes 2023.
Arguments:
x : float
$x$.
Returns:
out : float
$\Psi(x)$.
111def psi(x, mode="psi"): 112 r""" 113 A wrapper for different phase functions. 114 115 Inputs are scaled via `x_trans()` in all cases. 116 117 Arguments: 118 --- 119 - **x** : *float* 120 121 $x$. 122 123 - **mode** : *str* 124 125 Options are `'psi'` (corresponding to `psi_H()`), `'linear'` (corresponding to `psi_linear()`), `'quadratic'` (corresponding to `psi_quadratic()`), 126 `'sin'` (corresponding to `psi_sine()`). Default is `'psi'`. 127 128 Returns: 129 ---- 130 - **out** : *float* 131 132 $\Psi(x)$ for the $\Psi$ selected via `mode`. 133 134 135 """ 136 if mode=="sine": 137 out = psi_sine(x) 138 elif mode=="quadratic": 139 out = psi_quadratic(x) 140 elif mode=="linear": 141 out = psi_linear(x) 142 elif mode=="psi": 143 out = psi_H(x) 144 else: 145 raise ValueError('Unrecognised phase function mode. Options are "psi", "linear", "quadratic", "sine".') 146 147 return out
A wrapper for different phase functions.
Inputs are scaled via x_trans() in all cases.
Arguments:
x : float
$x$.
mode : str
Options are
'psi'(corresponding topsi_H()),'linear'(corresponding topsi_linear()),'quadratic'(corresponding topsi_quadratic()),'sin'(corresponding topsi_sine()). Default is'psi'.
Returns:
out : float
$\Psi(x)$ for the $\Psi$ selected via
mode.
149def psi_linear(x): 150 r""" 151 A simple linear phase function $\Psi$. 152 153 Arguments: 154 ---- 155 - **x** : *float* 156 157 $x$. 158 159 Returns: 160 ---- 161 - **out** : *float* 162 163 $\Psi(x) \sim x$. 164 165 """ 166 x = x_trans(x) 167 out= 0.5 + 0.01*x 168 169 return out
A simple linear phase function $\Psi$.
Arguments:
x : float
$x$.
Returns:
out : float
$\Psi(x) \sim x$.
171def psi_quadratic(x): 172 r""" 173 A simple quadratic phase function $\Psi$. 174 175 Arguments: 176 ---- 177 - **x** : *float* 178 179 $x$. 180 181 Returns: 182 ---- 183 - **out** : *float* 184 185 $\Psi(x) \sim x^2$. 186 187 """ 188 x = x_trans(x) 189 out= 0.0001* x**2 190 191 return out
A simple quadratic phase function $\Psi$.
Arguments:
x : float
$x$.
Returns:
out : float
$\Psi(x) \sim x^2$.
193def psi_sine(x): 194 r""" 195 A simple sinusoidal phase function $\Psi$. 196 197 Arguments: 198 ---- 199 - **x** : *float* 200 201 $x$. 202 203 Returns: 204 ---- 205 - **out** : *float* 206 207 $\Psi(x) \sim \sin x$. 208 209 """ 210 x = x_trans(x) 211 out = np.pi /2 *(1+ np.sin(x /4 )) 212 213 return out
A simple sinusoidal phase function $\Psi$.
Arguments:
x : float
$x$.
Returns:
out : float
$\Psi(x) \sim \sin x$.
215def get_phase_target(m, psi_mode, phase_reduce=True, mint=0): 216 r""" 217 218 Generate an array of phase function values taking into account rounding due to the limited 219 size of the target register. 220 221 The number of values in the array is determined for the same frequency scaling as in `x_trans()`. 222 223 Arguments: 224 --- 225 - **m** : *int* 226 227 Number of qubits in the target register. 228 229 - **psi_mode** : *str* 230 231 String specifying the phase function. Must be one of the options for the `mode` argument of `psi()`. 232 233 - **phase_reduce** : *boolean* 234 235 If True, phase function is reduced to the interval $[0, 2 \pi]$ before rounding. Default is True. 236 237 - **mint** : *int* 238 239 Number of integer qubits. Default is 0. 240 241 Returns: 242 --- 243 - **phase_rounded** : *array_like* 244 245 Array containing phase function values rounded to the precision 246 afforded by the target register size. 247 248 249 """ 250 251 # define x array 252 n = 6 253 x_min = 40 254 x_max = 168 255 dx = (x_max-x_min)/(2**n) 256 x_arr = np.arange(x_min, x_max, dx) 257 258 # calculate target output for phase 259 phase_target = psi(np.linspace(0, 2**n, len(x_arr)),mode=psi_mode) 260 261 # calculate target for phase taking into account rounding 262 if phase_reduce: 263 phase_reduced = np.modf(phase_target / (2* np.pi))[0] 264 phase_reduced_bin = [dec_to_bin(i,m, "unsigned mag", mint) for i in phase_reduced] 265 phase_reduced_dec = np.array([bin_to_dec(i,"unsigned mag", mint) for i in phase_reduced_bin]) 266 if phase_reduce: 267 phase_rounded = 2 * np.pi * phase_reduced_dec 268 269 return phase_rounded
Generate an array of phase function values taking into account rounding due to the limited size of the target register.
The number of values in the array is determined for the same frequency scaling as in x_trans().
Arguments:
m : int
Number of qubits in the target register.
psi_mode : str
String specifying the phase function. Must be one of the options for the
modeargument ofpsi().phase_reduce : boolean
If True, phase function is reduced to the interval $[0, 2 \pi]$ before rounding. Default is True.
mint : int
Number of integer qubits. Default is 0.
Returns:
phase_rounded : array_like
Array containing phase function values rounded to the precision afforded by the target register size.
272def A(x, mode="x76"): 273 r""" 274 A wrapper for different amplitude functions. 275 276 Arguments: 277 --- 278 - **x** : *float* 279 280 $x$. 281 282 - **mode** : *str* 283 284 Options are `'x76'` (corresponding to $A(x) \sim x^{-7/6}$), `'uniform'` (corresponding to $A(x) \sim 1$), and `'linear'` (corresponding to $A(x) \sim x$). 285 Default is `'x76'`. 286 287 Returns: 288 ---- 289 - **out** : *float* 290 291 $A(x)$ for the $A$ selected via `mode`. 292 293 294 """ 295 if mode=="x76": 296 out = x**(-7/6) 297 elif mode=="uniform": 298 out = 1 299 elif mode=="linear": 300 out= x 301 else: 302 raise ValueError('Unrecognised phase function mode. Options are "x76", "uniform", "linear".') 303 304 return out
A wrapper for different amplitude functions.
Arguments:
x : float
$x$.
mode : str
Options are
'x76'(corresponding to $A(x) \sim x^{-7/6}$),'uniform'(corresponding to $A(x) \sim 1$), and'linear'(corresponding to $A(x) \sim x$). Default is'x76'.
Returns:
out : float
$A(x)$ for the $A$ selected via
mode.