def exact(k, R1, R2, derivs): if (derivs): # Bessel evaluated at R1 J0_1 = special.j0(k * R1) Y0_1 = special.y0(k * R1) J1_1 = special.j1(k * R1) Y1_1 = special.y1(k * R1) # Bessel evaluated at R2 J0_2 = special.j0(k * R2) Y0_2 = special.y0(k * R2) J1_2 = special.j1(k * R2) Y1_2 = special.y1(k * R2) # # d Z1(k r)/dr = k*Z0(k r) - Z1(k r) / r # Jprime_1 = k * J0_1 - J1_1 / R1 Jprime_2 = k * J0_2 - J1_2 / R2 Yprime_1 = k * Y0_1 - Y1_1 / R1 Yprime_2 = k * Y0_2 - Y1_2 / R2 else: Jprime_1 = special.jvp(1, k * R1, 1) Jprime_2 = special.jvp(1, k * R2, 1) Yprime_1 = special.yvp(1, k * R1, 1) Yprime_2 = special.yvp(1, k * R2, 1) # F(k r) = J'_m(kr R1) * Y'_m(kr R2) - J'_m(kr R2) * Y'_m(kr R1) = 0 return Jprime_1 * Yprime_2 - Jprime_2 * Yprime_1
def g_int_lamarche(x, tt, Rt, rt, kt, gam, v): # tt = Fourier number # re = outer radius of the equivalent tube for concentric cylinders # rb = borehole radius # ks = soil thermal conductivity # kg = grout thermal conductivity # als = soil thermal diffusivity # alg = grout thermal diffusivity zeta1 = (1 - v * Rt * x**2) * y1(x) - v * x * y0(x) zeta2 = (1 - v * Rt * x**2) * j1(x) - v * x * j0(x) psi = (zeta2 * (j0(x * rt * gam) * y1(x * rt) - j1(x * rt * gam) * y0(x * rt) * kt * gam) - zeta1 * (j0(x * rt * gam) * j1(x * rt) - j1(x * rt * gam) * j0(x * rt) * kt * gam)) phi = (zeta1 * (y0(x * rt * gam) * j1(x * rt) - y1(x * rt * gam) * j0(x * rt) * kt * gam) - zeta2 * (y0(x * rt * gam) * y1(x * rt) - y1(x * rt * gam) * y0(x * rt) * kt * gam)) I = (1 - exp(-x**2 * tt)) / (x**5 * (phi**2 + psi**2)) return I
def cutoffHE1(b): a = rho * b i = ivp(1, u1 * a) / (u1 * a * i1(u1 * a)) X = (1 / (u1 * a)**2 + 1 / (u2 * a)**2) P = j1(u2 * a) * y1(u2 * b) - y1(u2 * a) * j1(u2 * b) Ps = (jvp(1, u2 * a) * y1(u2 * b) - yvp(1, u2 * a) * j1(u2 * b)) / (u2 * a) return (i * P + Ps) * (n12 * i * P + n22 * Ps) - n32 * X * X * P * P
def cutoffHE1(b): a = rho * b i = ivp(1, u1*a) / (u1*a * i1(u1*a)) X = (1 / (u1*a)**2 + 1 / (u2*a)**2) P = j1(u2*a) * y1(u2*b) - y1(u2*a) * j1(u2*b) Ps = (jvp(1, u2*a) * y1(u2*b) - yvp(1, u2*a) * j1(u2*b)) / (u2 * a) return (i * P + Ps) * (n12 * i * P + n22 * Ps) - n32 * X * X * P * P
def tetmConstants(self, ri, ro, neff, wl, EH, c, idx): a = numpy.empty((2, 2)) n = self.maxIndex(wl) u = self.u(ro, neff, wl) urp = self.u(ri, neff, wl) if neff < n: B1 = j0(u) B2 = y0(u) F1 = j0(urp) / B1 F2 = y0(urp) / B2 F3 = -j1(urp) / B1 F4 = -y1(urp) / B2 c1 = wl.k0 * ro / u else: B1 = i0(u) B2 = k0(u) F1 = i0(urp) / B1 F2 = k0(urp) / B2 F3 = i1(urp) / B1 F4 = -k1(urp) / B2 c1 = -wl.k0 * ro / u c3 = c * c1 a[0, 0] = F1 a[0, 1] = F2 a[1, 0] = F3 * c3 a[1, 1] = F4 * c3 return numpy.linalg.solve(a, EH.take(idx))
def gendata(X): l = '%5s%23s%23s%23s%23s%23s%23s\n' % ('x', 'J0', 'J1', 'J2', 'Y0', 'Y1', 'Y2') for i, x in enumerate(X): l += '%5.2f%23.15e%23.15e%23.15e%23.15e%23.15e%23.15e\n' % (x, sp.j0( x), sp.j1(x), sp.jv(2, x), sp.y0(x), sp.y1(x), sp.yn(2, x)) return l
def tetmConstants(self, ri, ro, neff, wl, EH, c, idx): a = numpy.empty((2, 2)) n = self.maxIndex(wl) u = self.u(ro, neff, wl) urp = self.u(ri, neff, wl) if neff < n: B1 = j0(u) B2 = y0(u) F1 = j0(urp) / B1 F2 = y0(urp) / B2 F3 = -j1(urp) / B1 F4 = -y1(urp) / B2 c1 = wl.k0 * ro / u else: B1 = i0(u) B2 = k0(u) F1 = i0(urp) / B1 F2 = k0(urp) / B2 F3 = i1(urp) / B1 F4 = -k1(urp) / B2 c1 = -wl.k0 * ro / u c3 = c * c1 a[0, 0] = F1 a[0, 1] = F2 a[1, 0] = F3 * c3 a[1, 1] = F4 * c3 return numpy.linalg.solve(a, EH.take(idx))
def load_date(): start = 10 end = 2000 data = pd.DataFrame({ "x": [x / 100 for x in range(start, end)], "y": [2 * x / 100 + 42 for x in range(start, end)], "z": [y1(x / 100) for x in range(start, end)] }) return (data)
def test_bessely_larger(self, dtype): x = np.random.uniform(1., 30., size=int(1e4)).astype(dtype) try: from scipy import special # pylint: disable=g-import-not-at-top self.assertAllClose( special.y0(x), self.evaluate(special_math_ops.bessel_y0(x))) self.assertAllClose( special.y1(x), self.evaluate(special_math_ops.bessel_y1(x))) except ImportError as e: tf_logging.warn('Cannot test special functions: %s' % str(e))
def green2dpar(k, r, z): ''' Return the 2-D Green's function for the parabolic wave equation for a total distance r, wave number k, and a distance z along the propagation axis. This formulation omits the exp(-ikz) factor present in Levy (2000) that converts the wave field into a slowly-varying function in z. Consequently, steps in z should be small with respect to wavelength. ''' h1 = spec.j1(k * r) + 1j * spec.y1(k * r) return 0.5j * k * z * h1 / r
def _z(self, omega): f = omega / (2. * np.pi) return np.sqrt(2. * self.c0 / self.h) \ * (1j * special.j0(4. * np.pi * f / self.alpha * np.sqrt(2. / (self.h * self.c0))) + special.y0(4. * np.pi * f / self.alpha * np.sqrt(2 / (self.h * self.c0)))) \ / (special.j1(4. * np.pi * f / self.alpha * np.sqrt(2. / (self.h * self.c0))) - 1j * special.y1(4. * np.pi * f / self.alpha * np.sqrt(2. / (self.h * self.c0))))
def G_int_sp(x_in): """Special function solution of G(x) (Coulomb integral) Defined in Eq. (17b) Mares and Chuang, J. Appl. Phys. 74, 1388 (1993) Keyword arguments: x_in -- Normalized 2|ze-zh|/lambda """ G = x_in*(sp.pi/2.0*(sps.struve(1,x_in)-sps.y1(x_in))-1) G[x_in <= 1.0E-8] = 1.0 return G
def gentable(X): # header l = '%5s %18s %13s %13s %13s %13s %13s\n' % ( 'x', 'J0(x)', 'J1(x)', 'J2(x)', 'Y0(x)', 'Y1(x)', 'Y2(x)') # table for i, x in enumerate(X): l += '%5.2f %18.15f %13.10f %13.10f %13.10f %13.10f %13.10f\n' % ( x, sp.j0(x), sp.j1(x), sp.jv(2, x), sp.y0(x), sp.y1(x), sp.yn( 2, x)) if (i + 1) % 5 == 0: l += '\n' return l
def transfRadMat(x, k, k_eq, eta_eq): ''' x = tiempo conforme k = modo (fijo) k_eq = tamanio del horizonte al momento de desacople eta_eq = tiempo conforme del desacople''' a = A(k, eta_eq) b = B(k, eta_eq) term1 = a * j1(k * x) term2 = b * y1(k * x) return eta_eq / x * (term1 * term2)
def _tmcoeq(self, v0, nu): u1r1, u2r1, u2r2, s1, s2, n1sq, n2sq, n3sq = self.__params(v0) if s1 == 0: # e f11a, f11b = 2, 1 elif s1 > 0: # a, b, d f11a, f11b = j0(u1r1) * u1r1, j1(u1r1) else: # c f11a, f11b = i0(u1r1) * u1r1, i1(u1r1) if s2 > 0: f22a, f22b = j0(u2r2), y0(u2r2) f2a = j1(u2r1) * f22b - y1(u2r1) * f22a f2b = j0(u2r1) * f22b - y0(u2r1) * f22a else: # a f22a, f22b = i0(u2r2), k0(u2r2) f2a = i1(u2r1) * f22b + k1(u2r1) * f22a f2b = i0(u2r1) * f22b - k0(u2r1) * f22a return f11a * n2sq * f2a - f11b * n1sq * f2b * u2r1
def _CHS(u, Fo, p): CHS_integrand = 1./(u**2*pi**2)*(np.exp(-u**2*Fo) - 1.0) / (j1(u)**2 + y1(u)**2) * (j0(p*u)*y1(u) - j1(u)*y0(p*2)) return CHS_integrand
b = 0.5 * P['C'] a = -1.0 w = 2. * np.pi * P['F'] t = np.asarray(P['T']) RHO = P['RHO'] U = np.absolute(P['V0']) THETA_MAX = P['THETA_MAX'] HEAVE_MAX = P['HEAVE_MAX'] PHI = P['PHI'] k = w * b / np.absolute(P['V0']) k2 = np.pi * P['F'] * P['C'] / np.absolute(P['V0']) St = 2. * P['F'] * P['HEAVE_MAX'] / np.absolute(P['V0']) F = (j1(k) * (j1(k) + y0(k)) + y1(k) * (y1(k) - j0(k))) / ((j1(k) + y0(k))**2 + (y1(k) - j0(k))**2) G = -(y1(k) * y0(k) + j1(k) * j0(k)) / ((j1(k) + y0(k))**2 + (y1(k) - j0(k))**2) L = -RHO * b**2 * ( U * np.pi * THETA_MAX * w * np.cos(w * t + PHI) - np.pi * HEAVE_MAX * w**2 * np.sin(w * t) + np.pi * b * a * THETA_MAX * w**2 * np.sin(w * t + PHI) ) - 2. * np.pi * RHO * U * b * F * ( U * THETA_MAX * np.sin(w * t + PHI) + HEAVE_MAX * w * np.cos(w * t) + b * (0.5 - a) * THETA_MAX * w * np.cos(w * t + PHI) ) - 2. * np.pi * RHO * U * b * G * ( U * THETA_MAX * np.cos(w * t + PHI) - HEAVE_MAX * w * np.sin(w * t) - b * (0.5 - a) * THETA_MAX * w * np.sin(w * t + PHI)) Cl = np.real(L) / (0.5 * P['RHO'] * np.absolute(P['V0'])**2 * P['C'])
T_b_uls[i] = T_g + (q/(2*m.pi*k_g))*I_int[i] #------------------------------------------------------------------------------ # Evaluerer sylindersluk-løsningen #------------------------------------------------------------------------------ Fo = np.zeros(n) # Fourier-tallet G = np.zeros(s) # Sylindersluk-funksjonen T_b_uss = np.zeros(s) # Temperatur ved borehullveggen for uss løsningen for i in range(n): # Fouriertallet Fo[i] = (a_g/(r_b**2))*tid[i] # Beregner integralet i sylindersluk-funksjonen G[i] = integrate.quad(lambda h:((np.exp(-(h**2)*Fo[i]))-1)*((sp.j0(h)*sp.y1(h) - sp.y0(h)*sp.j1(h))/((h**2)*((sp.j1(h)**2)+(sp.y1(h)**2)))),0,m.inf) # Temperatur ved borehullveggen T_b_uss[i] = T_g + q/(k_g*(np.pi**2))*G[i] #------------------------------------------------------------------------------ # Temperaturprofilen ved borehullveggen for de ulike modellene #------------------------------------------------------------------------------ line1, = ax1.plot(tid_skala, T_b_pyg,'k-', lw=1.5, label='Pygfunction' ) line2, = ax1.plot(tid_skala, T_b_uls[:,0], 'r-', lw=1.5, label='u_linjesluk') line3, = ax1.plot(tid_skala, T_b_uss[:,0], 'y-', lw=1.5, label='u_sylindersluk')
def synth_flats(projData3D_clean, source_intensity, source_variation, arguments_Bessel, specklesize, kbar, sigmasmooth, jitter, flatsnum): """ the required format of the input (clean) data is [detectorsX, Projections, detectorsY] Parameters: source_intensity - source intensity which affects the amount of Poisson noise added to data source_variation - constant which perturbs the source intensity leading to ring artifacts etc. arguments_Bessel - tuple of 4 Arguments for 2 Bessel functions to control background variations specklesize - speckle size in pixel units for background simulation kbar - mean photon density (photons per pixel) for background simulation jitter - a random jitter to the speckled background given in pixels sigmasmooth - Gaussian smoothing parameter to blur the speckled backround (1,3,5,7...) flatsnum - a number of flats to generate """ [DetectorsDimV, projectionsNo, DetectorsDimH] = np.shape(projData3D_clean) flatfield = np.zeros((DetectorsDimV, DetectorsDimH)) blurred_speckles = np.zeros((DetectorsDimV, DetectorsDimH)) blurred_speckles_res = np.zeros((DetectorsDimV, DetectorsDimH)) flats_combined3D = np.zeros((DetectorsDimV, flatsnum, DetectorsDimH)) projData3D_noisy = np.zeros(np.shape(projData3D_clean), dtype='float32') source_intensity_var = source_intensity * np.ones( (DetectorsDimV, DetectorsDimH)) source_intensity_variable = source_intensity_var maxProj_scalar = np.max(projData3D_clean) # using spherical Bessel functions to emulate the background (scintillator) variations func = spherical_yn( 1, np.linspace(arguments_Bessel[0], arguments_Bessel[1], DetectorsDimV, dtype='float32')) func = func + abs(np.min(func)) func2 = y1( np.linspace(arguments_Bessel[2], arguments_Bessel[3], DetectorsDimH, dtype='float32')) func2 = func2 + abs(np.min(func2)) for i in range(0, DetectorsDimV): flatfield[i, :] = func2 for i in range(0, DetectorsDimH): flatfield[:, i] += func if (specklesize != 0.0): # using speckle generator routines to create a texture in the background modes = 1 speckle_background = simulate_speckles_with_shot_noise( [DetectorsDimV, DetectorsDimH], modes, specklesize, kbar) #blur the speckled background and add to the initial image with the Bessel background blurred_speckles = gaussian_filter(speckle_background.copy(), sigma=sigmasmooth) for i in range(0, flatsnum): # adding noise and normalise if (jitter != 0.0): horiz_shift = random.uniform( -jitter, jitter) #generate random directional shift vert_shift = random.uniform( -jitter, jitter) #generate random directional shift blurred_speckles_res = shift(blurred_speckles.copy(), [vert_shift, horiz_shift]) else: blurred_speckles_res = blurred_speckles flat_combined = flatfield + blurred_speckles_res flat_combined /= np.max(flat_combined) # make source intensity variable if required if (source_variation is not None or source_variation != 0.0): source_intensity_variable = noise(source_intensity_var, source_variation * source_intensity, noisetype='Gaussian', seed=None, prelog=None) #adding Poisson noise to the flat fields flat_noisy = np.random.poisson( np.multiply(source_intensity_variable, flat_combined)) flats_combined3D[:, i, :] = flat_noisy for i in range(0, projectionsNo): # make source intensity variable if required if (source_variation is not None or source_variation != 0.0): source_intensity_variable = noise(source_intensity_var, source_variation * source_intensity, noisetype='Gaussian', seed=None, prelog=None) # adding noise and normalise if (jitter != 0.0): horiz_shift = random.uniform( -jitter, jitter) #generate random directional shift vert_shift = random.uniform( -jitter, jitter) #generate random directional shift blurred_speckles_res = shift(blurred_speckles.copy(), [vert_shift, horiz_shift]) else: blurred_speckles_res = blurred_speckles flat_combined = flatfield + blurred_speckles_res flat_combined /= np.max(flat_combined) projData3D_noisy[:, i, :] = np.random.poisson( np.random.poisson( np.multiply(source_intensity_variable, flat_combined)) * np.exp(-projData3D_clean[:, i, :] / maxProj_scalar)) return [projData3D_noisy, flats_combined3D]
# aksegrenser ax1.set_xlim([0., 20.]) ax1.set_ylim([-1, 1.1]) # ticks ax1.xaxis.set_minor_locator(AutoMinorLocator()) ax1.yaxis.set_minor_locator(AutoMinorLocator()) #grid ax1.grid(color='k', linestyle='--', linewidth=0.1) # Justering av plottvindu plt.tight_layout() # x - verdier x = np.linspace(0, 20, num=500) # Bessel-integral av 1. orden J0 = special.j0(x) J1 = special.j1(x) # Bessel-integral av 2. orden Y0 = special.y0(x) Y1 = special.y1(x) # Tegner Besselfunksjoner av 1. og 2. orden line1, = ax1.plot(x, J0, 'r-', markersize=0.5, label='J0') line2, = ax1.plot(x, J1, 'k-', markersize=0.5, label='J1') line3, = ax1.plot(x, Y0, 'y-', markersize=0.5, label='Y0') line4, = ax1.plot(x, Y1, 'b-', markersize=0.5, label='Y1') plt.legend(handler_map={line4: HandlerLine2D(numpoints=4)}, loc=1) plt.show()
def ddphi(lam, r): ddphir = -lam * ((Jp(1, lam * r) * y1(lam)) - (j1(lam) * Yp(1, lam * r))) return ddphir
def dphi(lam, r): dphir = -lam * ((j1(lam * r) * y1(lam)) - (j1(lam) * y1(lam * r))) return dphir
def phi(lam, r): phir = (j0(lam * r) * y1(lam)) - (j1(lam) * y0(lam * r)) return phir
def synth_flats(projData3D_clean, source_intensity, source_variation, arguments_Bessel, strip_height, strip_thickness, sigmasmooth, flatsnum): """ the required format of the input (clean) data is [detectorsX, Projections, detectorsY] Parameters: source_intensity - a source intensity which affects the amount of Poisson noise added to data source_variation - a constant which perturbs the source intensity leading to ring artifacts etc. arguments_Bessel - a tuple of 4 Arguments for 2 Bessel functions to control background variations strip_height - a value between (0,1] which controls the height of the background stripes strip_thickness - a value in pixels which controls the width of stripes sigmasmooth - a smoothing parameter for a stripe image with noise (1,3,5,7...) flatsnum - a number of flats to generate """ [DetectorsDimV, projectionsNo, DetectorsDimH] = np.shape(projData3D_clean) flatfield = np.zeros((DetectorsDimV, DetectorsDimH)) flats_combined3D = np.zeros((DetectorsDimV, flatsnum, DetectorsDimH)) projData3D_noisy = np.zeros(np.shape(projData3D_clean), dtype='float32') source_intensity_var = source_intensity * np.ones( (DetectorsDimV, DetectorsDimH)) source_intensity_variable = source_intensity_var maxProj_scalar = np.max(projData3D_clean) # using spherical Bessel functions to emulate the background (scintillator) variations func = spherical_yn( 1, np.linspace(arguments_Bessel[0], arguments_Bessel[1], DetectorsDimV, dtype='float32')) func = func + abs(np.min(func)) func2 = y1( np.linspace(arguments_Bessel[2], arguments_Bessel[3], DetectorsDimH, dtype='float32')) func2 = func2 + abs(np.min(func2)) for i in range(0, DetectorsDimV): flatfield[i, :] = func2 for i in range(0, DetectorsDimH): flatfield[:, i] += func # Adding stripes of varying vertical & horizontal sizes maxheight_par = round(strip_height * DetectorsDimV) max_intensity = np.max(flatfield) flatstripes = np.zeros(np.shape(flatfield)) for x in range(0, DetectorsDimH): randind = random.randint( 0, DetectorsDimV) # generate random index (vertically) randthickness = random.randint( 0, strip_thickness) #generate random thickness randheight = random.randint(0, maxheight_par) #generate random height randintens = random.uniform(0.1, 2.0) # generate random multiplier intensity = max_intensity * randintens for x1 in range(-randheight, randheight): if (((randind + x1) >= 0) and ((randind + x1) < DetectorsDimV)): for x2 in range(-randthickness, randthickness): if (((x + x2) >= 0) and ((x + x2) < DetectorsDimH)): flatstripes[randind + x1, x + x2] += intensity for i in range(0, flatsnum): # adding noise and normalise flatstripes2 = flatstripes.copy() #blur the result and add to the initial image with the Bessel background blurred_flatstripes = gaussian_filter(flatstripes2, sigma=sigmasmooth) flat_combined = flatfield + blurred_flatstripes flat_combined /= np.max(flat_combined) # make source intensity variable if required if (source_variation is not None or source_variation != 0.0): source_intensity_variable = noise(source_intensity_var, source_variation * source_intensity, noisetype='Gaussian', seed=None, prelog=None) #adding Poisson noise to the flat fields flat_noisy = np.random.poisson( np.multiply(source_intensity_variable, flat_combined)) flats_combined3D[:, i, :] = flat_noisy for i in range(0, projectionsNo): # make source intensity variable if required if (source_variation is not None or source_variation != 0.0): source_intensity_variable = noise(source_intensity_var, source_variation * source_intensity, noisetype='Gaussian', seed=None, prelog=None) projData3D_noisy[:, i, :] = np.random.poisson( np.random.poisson( np.multiply(source_intensity_variable, flat_combined)) * np.exp(-projData3D_clean[:, i, :] / maxProj_scalar)) return [projData3D_noisy, flats_combined3D]
b = 0.5 * P['C'] a = -1.0 w = 2. * np.pi * P['F'] t = np.asarray(P['T']) RHO = P['RHO'] U = np.absolute(P['V0']) THETA_MAX = P['THETA_MAX'] HEAVE_MAX = P ['HEAVE_MAX'] PHI = P['PHI'] k = w * b / np.absolute(P['V0']) k2 = np.pi * P['F'] * P['C'] / np.absolute(P['V0']) St = 2. * P['F'] * P['HEAVE_MAX'] / np.absolute(P['V0']) F = (j1(k)*(j1(k)+y0(k)) + y1(k)*(y1(k)-j0(k))) / ((j1(k)+y0(k))**2 + (y1(k)-j0(k))**2) G = -(y1(k)*y0(k) + j1(k)*j0(k)) / ((j1(k)+y0(k))**2 + (y1(k)-j0(k))**2) L = -RHO * b**2 * (U * np.pi * THETA_MAX * w * np.cos(w * t + PHI) - np.pi * HEAVE_MAX * w**2 * np.sin(w * t) + np.pi * b * a * THETA_MAX * w**2 * np.sin(w * t + PHI)) - 2. * np.pi * RHO * U * b * F * (U * THETA_MAX * np.sin(w * t + PHI) + HEAVE_MAX * w * np.cos(w * t) + b * (0.5 - a) * THETA_MAX * w * np.cos(w * t + PHI)) - 2. * np.pi * RHO * U * b * G * (U * THETA_MAX * np.cos(w * t + PHI) - HEAVE_MAX * w * np.sin(w * t) - b * (0.5 - a) * THETA_MAX * w * np.sin(w * t + PHI)) Cl = np.real(L) / (0.5 * P['RHO'] * np.absolute(P['V0'])**2 * P['C']) execfile("rigid_bem2d.py") expCsv = np.genfromtxt('forces.csv', delimiter=',') #P['SW_KUTTA'] = True # #execfile("rigid_bem2d_kutta.py") #impCsv = np.genfromtxt('forces.csv', delimiter=',') #Determine Error
def g_int(x, Fo, rt): num = exp(-Fo * x**2) - 1 den = x**2 * (j1(x)**2 + y1(x)**2) I = num / den * (j0(rt * x) * y1(x) - y0(rt * x) * j1(x)) return I
def G(a, gamma): if abs(gamma) < 1.0e-9: return 1.0 else: x = 2 * abs(gamma) / a return x * (np.pi / 2 * (sp.struve(1, x) - sp.y1(x)) - 1)