def __compute_t_r(self,n_lobes,lobe_idx,H_in,Hr,d_eval,p4roots,lead_cf): from pyranha import math from mpmath import asin, sqrt, ellipf, mpf assert(n_lobes == 1 or n_lobes == 2) C = -lead_cf assert(C > 0) # First determine if we are integrating in the upper or lower plane. # NOTE: we don't care about eps, we are only interested in the sign. if (self.__F1 * math.sin(pt('h_\\ast'))).trim().evaluate(d_eval) > 0: sign = 1 else: sign = -1 if n_lobes == 2: assert(lobe_idx == 0 or lobe_idx == 1) r0,r1,r2,r3 = p4roots # k is the same in both cases. k = sqrt(((r3-r2)*(r1-r0))/((r3-r1)*(r2-r0))) if lobe_idx == 0: assert(Hr == r0) phi = asin(sqrt(((r3-r1)*(H_in-r0))/((r1-r0)*(r3-H_in)))) else: assert(Hr == r2) phi = asin(sqrt(((r3-r1)*(H_in-r2))/((H_in-r1)*(r3-r2)))) return -sign * mpf(2) / sqrt(C * (r3 - r1) * (r2 - r0)) * ellipf(phi,k**2) else: # TODO: single lobe case. assert(False) pass
def _view_cone_calc(lat_geoc, lon_geoc, sat_pos, sat_vel, q_max, m): """Semi-private: Performs the viewing cone visibility calculation for the day defined by m. Note: This function is based on a paper titled "rapid satellite-to-site visibility determination based on self-adaptive interpolation technique" with some variation to account for interaction of viewing cone with the satellite orbit. Args: lat_geoc (float): site location in degrees at the start of POI lon_geoc (float): site location in degrees at the start of POI sat_pos (Vector3D): position of satellite (at the same time as sat_vel) sat_vel (Vector3D): velocity of satellite (at the same time as sat_pos) q_max (float): maximum orbital radius m (int): interval offsets (number of days after initial condition) Returns: Returns 4 numbers representing times at which the orbit is tangent to the viewing cone, Raises: ValueError: if any of the 4 formulas has a complex answer. This happens when the orbit and viewing cone do not intersect or only intersect twice. Note: With more analysis it should be possible to find a correct interval even in the case where there are only two intersections but this is beyond the current scope of the project. """ lat_geoc = (lat_geoc * mp.pi) / 180 lon_geoc = (lon_geoc * mp.pi) / 180 # P vector (also referred to as orbital angular momentum in the paper) calculations p_unit_x, p_unit_y, p_unit_z = cross(sat_pos, sat_vel) / (mp.norm(sat_pos) * mp.norm(sat_vel)) # Following are equations from Viewing cone section of referenced paper r_site_magnitude = earth_radius_at_geocetric_lat(lat_geoc) gamma1 = THETA_NAUGHT + mp.asin((r_site_magnitude * mp.sin((mp.pi / 2) + THETA_NAUGHT)) / q_max) gamma2 = mp.pi - gamma1 # Note: atan2 instead of atan to get the correct quadrant. arctan_term = mp.atan2(p_unit_x, p_unit_y) arcsin_term_gamma, arcsin_term_gamma2 = [(mp.asin((mp.cos(gamma) - p_unit_z * mp.sin(lat_geoc)) / (mp.sqrt((p_unit_x ** 2) + (p_unit_y ** 2)) * mp.cos(lat_geoc)))) for gamma in [gamma1, gamma2]] angle_1 = (arcsin_term_gamma - lon_geoc - arctan_term + 2 * mp.pi * m) angle_2 = (mp.pi - arcsin_term_gamma - lon_geoc - arctan_term + 2 * mp.pi * m) angle_3 = (arcsin_term_gamma2 - lon_geoc - arctan_term + 2 * mp.pi * m) angle_4 = (mp.pi - arcsin_term_gamma2 - lon_geoc - arctan_term + 2 * mp.pi * m) angles = [angle_1, angle_2, angle_3, angle_4] # Check for complex answers if any([not isinstance(angle, mp.mpf) for angle in angles]): raise ValueError() # Map all angles to 0 to 2*pi for idx in range(len(angles)): while angles[idx] < 0: angles[idx] += 2 * mp.pi while angles[idx] > 2 * mp.pi: angles[idx] -= 2 * mp.pi # Calculate the corresponding time for each angle and return return [mp.nint((1 / ANGULAR_VELOCITY_EARTH) * angle) for angle in angles]
def Pinv(self, P): from mpmath import ellipf, sqrt, asin, acos, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: P = -P if Delta > 0: m = (e2 - e3) / (e1 - e3) retval = (1 / sqrt(e1 - e3)) * ellipf( asin(sqrt((e1 - e3) / (P - e3))), m=m) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert (H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) retval = 1 / (2 * sqrt(H2)) * ellipf(acos( (e2 - P + H2) / (e2 - P - H2)), m=m) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / sqrt(P) else: c = e1 / 2 retval = (1 / sqrt(3 * c)) * asin(sqrt((3 * c) / (P + c))) if self.__ng3: retval /= mpc(0, 1) alpha, beta, _, _ = self.reduce_to_fpp(retval) T1, T2 = self.periods return T1 * alpha + T2 * beta
def Pinv(self,P): from mpmath import ellipf, sqrt, asin, acos, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: P = -P if Delta > 0: m = (e2 - e3) / (e1 - e3) retval = (1 / sqrt(e1 - e3)) * ellipf(asin(sqrt((e1 - e3)/(P - e3))),m=m) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) retval = 1 / (2 * sqrt(H2)) * ellipf(acos((e2-P+H2)/(e2-P-H2)),m=m) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / sqrt(P) else: c = e1 / 2 retval = (1 / sqrt(3 * c)) * asin(sqrt((3 * c)/(P + c))) if self.__ng3: retval /= mpc(0,1) alpha, beta, _, _ = self.reduce_to_fpp(retval) T1, T2 = self.periods return T1 * alpha + T2 * beta
def set_polar_coordinate(self): from math import asin, cos self.phi = asin(self.z / self.norm) sintheta = self.y / (self.norm * cos(self.phi)) self.theta = asin(sintheta) self.adjust_polar_coordinate()
def set_polar_coordinate(self): from mpmath import asin, cos, chop self.phi = asin(self.z / self.norm) sintheta = chop(self.y / (self.norm * cos(self.phi))) theta = asin(sintheta) self.theta = theta
def inverse_sine(): """Inverse sine function. The inverse ine or arcsine of x, sin**-1(x), since -1 <= sin(x) <= 1 for real x, the inverse sine is real-valued for -1 <= x <= 1, or defined monotonically increasing assuming values between -pi/2 and pi/2. """ import mpmath print(mpmath.asin(-1), mpmath.asin(0), mpmath.asin(1))
def do_approximation(self): epsilonp = np.sqrt(np.power(10, self.Ap / 10) - 1) gp = np.power(10, -self.Ap / 20) k1 = np.sqrt((np.power(10, self.Ap / 10) - 1) / (np.power(10, self.Ao / 10) - 1)) k = 1 / self.wan a = mp.asin(1j / epsilonp) vo = mp.ellipf(1j / epsilonp, k1) / (1j * self.n) self.n = np.ceil( special.ellipk(np.sqrt(1 - np.power(k1, 2))) * special.ellipk(k) / (special.ellipk(k1) * special.ellipk(np.sqrt(1 - np.power(k, 2))))) for i in range(1, int(np.floor(self.n / 2)) + 1): cd = mp.ellipfun('cd', (2 * i - 1) / self.n, k) zero = (1j / (float(k * cd.real) + 1j * float(k * cd.imag))) self.num = self.num * np.poly1d([1 / zero, 1]) self.num = self.num * np.poly1d([1 / np.conj(zero), 1]) cd = mp.ellipfun('cd', (2 * i - 1) / self.n - 1j * vo, k) pole = 1j * (float(cd.real) + 1j * float(cd.imag)) if np.real(pole) <= 0: self.den = self.den * np.poly1d([-1 / pole, 1]) self.den = self.den * np.poly1d([-1 / np.conj(pole), 1]) if np.mod(self.n, 2) == 1: sn = 1j * mp.ellipfun('sn', 1j * vo, k) pole = 1j * (float(sn.real) + 1j * float(sn.imag)) if np.real(pole) <= 0: self.den = self.den * np.poly1d([-1 / pole, 1]) self.den = self.den * np.poly1d([-1 / np.conj(pole), 1]) self.zeroes = np.roots(self.num) self.poles = np.roots(self.den) self.aprox_gain = np.power(gp, 1 - (self.n - 2 * np.floor(self.n / 2))) self.num = self.num * self.aprox_gain self.norm_sys = signal.TransferFunction( self.num, self.den) #Filter system is obtained
def get_dtheta_at(self, phi, covered_r): from math import asin, cos, sqrt, pi if covered_r >= sqrt(2) * cos(phi): # In this case, the confidence radius is so large such that it covers the whole orbit and the north pole. dtheta = pi else: dtheta = 2 * asin((.5 * covered_r) / cos(phi)) return dtheta
def one_side(x,y): m = ((-1 + x)*(1 + y))/((1 + x)*(-1 + y)) k = sqrt(m) u = asin(1/k) EE = ellipe(m) EF = re(ellipf(u,m)) n = (-1 + x)/(-1 + y) EPI = ellippi(n/m,1/m)/k #EPI = ellippi(n,u,m) return re(-(EE*(1 + x)*(-1 + y) + (x - y)*(EF + EPI*(x-y) + EF*y))/sqrt(((1 + x)*(1 - y))))
def equiv_sin(x, range1, range2, radians=None, degrees=None, accuracy=2): mpmath.mp.dps = accuracy + 1 range1, range2 = TrigEquivAngle.deg_or_rad([range1, range2], degrees) firstSinAngle = mpmath.asin(x) secondSinAngle = mpmath.pi - firstSinAngle angles = TrigEquivAngle.create_equiv_angle_list( [firstSinAngle, secondSinAngle], range1, range2, 2 * mpmath.pi) return (TrigEquivAngle.clean_angles_rad_deg(angles, radians, degrees, accuracy))
def go_down(phi, r): # It returns the orbit new_phi which is below phi and has distance r # (on the sphere on which our directions are located) from math import asin, sin, pi if sin(phi) - r >= -1: new_phi = asin(sin(phi) - r) else: new_phi = -pi / 2 return new_phi
def __compute_tau_eta(self): # Gradshtein 3.131.5. from mpmath import sqrt, asin, ellipf u = self.__init_coordinates[1]**2 / 2 c,b,a = self.__roots_eta k = asin(sqrt(((a - c) * (u - b)) / ((a - b) * (u - c)))) p = sqrt((a - b) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(k,p**2) if self.__init_momenta[1] >= 0: return -abs(retval) else: return abs(retval)
def __compute_tau_eta(self): # Gradshtein 3.131.5. from mpmath import sqrt, asin, ellipf u = self.__init_coordinates[1]**2 / 2 c, b, a = self.__roots_eta k = asin(sqrt(((a - c) * (u - b)) / ((a - b) * (u - c)))) p = sqrt((a - b) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(k, p**2) if self.__init_momenta[1] >= 0: return -abs(retval) else: return abs(retval)
def __compute_tau_xi(self): from mpmath import sqrt, asin, ellipf, mpc, atan if self.bound: # Gradshtein 3.131.3. u = self.__init_coordinates[0]**2 / 2 c, b, a = self.__roots_xi gamma = asin(sqrt((u - c) / (b - c))) q = sqrt((b - c) / (a - c)) # NOTE: here it's q**2 instead of q because of the difference in # convention between G and mpmath :( # NOTE: the external factor 1 / sqrt(8 * self.eps) comes from the fact # that G gives the formula for a polynomial normalised by its leading coefficient. retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf( gamma, q**2) else: # Here we will need two cases: one for when the other two roots are real # but negative, one for when the other two roots are imaginary. if isinstance(self.__roots_xi[1], mpc): # G 3.138.7. m = self.__roots_xi[1].real n = abs(self.__roots_xi[1].imag) # Only real root is the first one. a = self.__roots_xi[0] u = self.__init_coordinates[0]**2 / 2 p = sqrt((m - a)**2 + n**2) retval = 1 / sqrt(8 * self.eps) * (1 / sqrt(p)) * ellipf( 2 * atan(sqrt((u - a) / p)), (p + m - a) / (2 * p)) else: # G 3.131.7. u = self.__init_coordinates[0]**2 / 2 c, b, a = self.__roots_xi mu = asin(sqrt((u - a) / (u - b))) q = sqrt((b - c) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf( mu, q**2) # Fix the sign according to the initial momentum. if self.__init_momenta[0] >= 0: return -abs(retval) else: return abs(retval)
def __compute_tau_xi(self): from mpmath import sqrt, asin, ellipf, mpc, atan if self.bound: # Gradshtein 3.131.3. u = self.__init_coordinates[0]**2 / 2 c,b,a = self.__roots_xi gamma = asin(sqrt((u - c)/(b - c))) q = sqrt((b - c)/(a - c)) # NOTE: here it's q**2 instead of q because of the difference in # convention between G and mpmath :( # NOTE: the external factor 1 / sqrt(8 * self.eps) comes from the fact # that G gives the formula for a polynomial normalised by its leading coefficient. retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(gamma,q**2) else: # Here we will need two cases: one for when the other two roots are real # but negative, one for when the other two roots are imaginary. if isinstance(self.__roots_xi[1],mpc): # G 3.138.7. m = self.__roots_xi[1].real n = abs(self.__roots_xi[1].imag) # Only real root is the first one. a = self.__roots_xi[0] u = self.__init_coordinates[0]**2 / 2 p = sqrt((m - a)**2 + n**2) retval = 1 / sqrt(8 * self.eps) * (1 / sqrt(p)) * ellipf(2 * atan(sqrt((u - a) / p)),(p + m - a) / (2*p)) else: # G 3.131.7. u = self.__init_coordinates[0]**2 / 2 c,b,a = self.__roots_xi mu = asin(sqrt((u - a)/(u - b))) q = sqrt((b - c)/(a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(mu,q**2) # Fix the sign according to the initial momentum. if self.__init_momenta[0] >= 0: return -abs(retval) else: return abs(retval)
def elliptic_core_g(x,y): x = x/2 y = y/2 factor = (cos(x)/sin(y) + sin(y)/cos(x) - (cos(y)/tan(y)/cos(x) + sin(x)*tan(x)/sin(y)))/pi k = tan(x)/tan(y) m = k*k n = (sin(x)/sin(y))*(sin(x)/sin(y)) u = asin(tan(y)/tan(x)) complete = ellipk(m) - ellippi(n, m) incomplete = ellipf(u,m) - ellippi(n/k/k,1/m)/k #incomplete = ellipf(u,m) - ellippi(n,u,m) return re(1.0 - factor*(incomplete + complete))
def calc_abel(k, zeta, eta): k1 = sqrt(1 - k**2) a = k1 + complex(0, 1) * k b = k1 - complex(0, 1) * k abel_tmp = map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) abel = [] for i in range(0, 4, 1): abel.append(abel_select(k, abel_tmp[i], eta[i])) return abel
def calc_abel(k, zeta, eta): k1 = sqrt(1-k**2) a=k1+complex(0, 1)*k b=k1-complex(0, 1)*k abel_tmp = map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) abel = [] for i in range(0, 4, 1): abel.append(abel_select(k, abel_tmp[i], eta[i])) return abel
def which_cannot_cover_with_half_radius(self, v: NormalVector, shift=0): from math import asin, pi d = self.checked_discrepancy_upper_bound r = v.expected_radius half_r = r / 2 distance_to_center = .86 * r larger_r = distance_to_center + r phi_arround_pole = asin(r_to_dot(distance_to_center)) dtheta = 2 * pi / self.cap_covering_number candidates = [NormalVector(theta=0, phi=pi / 2)] candidates += [ NormalVector(phi=phi_arround_pole, theta=shift + (i * dtheta)) for i in range(self.cap_covering_number) ] rotation = get_rotation_matrix_north_pole_to(theta=v.theta, phi=v.phi) cannot_cover = [] for cand_v in candidates: cand_v.rotate(rotation) discrepancy, projection = self.get_discrepancy_data(cand_v) if discrepancy >= d: return "found higher discrepancy at", cand_v, candidates else: cr = self.get_confidence_radius(d=d, discrepancy=discrepancy, projection=projection) cand_v.set_discrepancy_data(discrepancy=discrepancy, confidence_radius=cr, expected_radius=half_r) if cr >= larger_r: return "all covered by", cand_v, candidates elif cr < half_r: cannot_cover += [cand_v] return "cannot list", cannot_cover, candidates
def test_on_line(k, x0, x1, y, z, partition_size): k1 = sqrt(1 - k**2) a = k1 + complex(0, 1) * k b = k1 - complex(0, 1) * k x_step = (x1 - x0) / partition_size for i in range(0, partition_size): x = x0 + i * x_step zeta = calc_zeta(k, x, y, z) eta = calc_eta(k, x, y, z) abel = calc_abel(k, zeta, eta) mu = calc_mu(k, x, y, z, zeta, abel) print "zeta/a", zeta[0] / a, zeta[1] / a, zeta[2] / a, zeta[3] / a, '\n' print "eta", eta[0], eta[1], eta[2], eta[3], '\n' print "abel", abel[0], abel[1], abel[2], abel[3], '\n' abel_tmp= map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) print "abel_tmp", abel_tmp[0], abel_tmp[1], abel_tmp[2], abel_tmp[ 3], '\n' print abel[0] + conj(abel[2]), abel[1] + conj(abel[3]), '\n' print -taufrom(k=k) / 2, '\n' for l in range(0, 4): tmp = abs(complex64(calc_eta_by_theta(k, abel[l])) - eta[l]) print tmp value = higgs_squared(k, x, y, z) print "higgs", higgs_squared(k, x, y, z) if (value > 1.0 or value < 0.0): print "Exception" print '\n' # print mu[0]+mu[2], mu[1]+mu[3], '\n' return
def test_on_line(k, x0, x1, y, z, partition_size): k1 = sqrt(1-k**2) a=k1+complex(0, 1)*k b=k1-complex(0, 1)*k x_step = (x1 - x0) / partition_size for i in range(0, partition_size): x=x0+i*x_step zeta = calc_zeta(k ,x, y, z) eta = calc_eta(k, x, y, z) abel = calc_abel(k, zeta, eta) mu = calc_mu(k, x, y, z, zeta, abel) print "zeta/a", zeta[0]/a, zeta[1]/a, zeta[2]/a, zeta[3]/a, '\n' print "eta", eta[0], eta[1], eta[2], eta[3], '\n' print "abel", abel[0], abel[1],abel[2],abel[3],'\n' abel_tmp= map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) print "abel_tmp", abel_tmp[0], abel_tmp[1],abel_tmp[2],abel_tmp[3],'\n' print abel[0]+conj(abel[2]), abel[1]+conj(abel[3]), '\n' print - taufrom(k=k)/2, '\n' for l in range(0,4): tmp= abs(complex64(calc_eta_by_theta(k, abel[l])) - eta[l]) print tmp value = higgs_squared(k, x, y, z) print "higgs", higgs_squared(k,x,y,z) if (value > 1.0 or value <0.0): print "Exception" print '\n' # print mu[0]+mu[2], mu[1]+mu[3], '\n' return
def calc_lambda_r(r, r1, r2, r3, r4, En): """ Mino time as a function of r (which in turn is a function of psi) Parameters: r (float): radius r1 (float): radial root r2 (float): radial root r3 (float): radial root r4 (float): radial root En (float): energy Returns: lambda (float) """ kr = ((r1 - r2) * (r3 - r4)) / ((r1 - r3) * (r2 - r4)) # if r1 == r2: # # circular orbit # print('Circular orbits currently do not work.') # return 0 yr = sqrt(((r - r2) * (r1 - r3)) / ((r1 - r2) * (r - r3))) F_asin = ellipf(asin(yr), kr) return (2 * F_asin) / (sqrt(1 - En * En) * sqrt((r1 - r3) * (r2 - r4)))
def make_polar_coordinate(self, n, is_twisted=True, precision=30, log_scale=0): # This function distribute points with polar coordinate on sphere. This algorithm is O (n^2). # It also returns a phi above which we know north pole is a local maximum. from mpmath import mp, sin, cos, sqrt, pi, floor, mpf, asin from numpy import array, cross from numpy.linalg import norm from os import remove mp.dps = precision remove(self.points_address) if is_twisted: name = "twisted_polar_coordinates_" + str(n) self.point_set = PointSet(name=name, address=self.output_folder) else: name = "polar_coordinates_" + str(n) self.point_set = PointSet(name=name, address=self.output_folder) self.points_address = self.point_set.point_file_address if not float(Point._log_scale) == log_scale: Point.change_log_scale(log_scale) print("Point scale is", Point.get_scale()) if not Point._precision == precision: Point.change_precision(precision) phis = [0] * (n - 1) m = [0] * (n - 1) for j in range(n - 1): phis[j] = ((pi * (j + 1)) / n) - (pi / 2) m[j] = int(floor(mpf(".5") + sqrt(3) * n * cos(phis[j]))) for j in range(n - 1): for i in range(m[j]): if is_twisted: if j + 1 < n / 2: shift = (2 * pi * (j + 1)) / (n * m[j]) else: shift = (2 * pi * (1 - mpf(j + 1) / mpf(n))) / m[j] else: shift = 0 theta = ((2 * pi * i) / m[j]) + shift new_point = Point(theta=theta, phi=phis[j]) self.point_set.add_point(new_point) north_pole = Point(theta=0, phi=pi / 2) south_pole = Point(theta=0, phi=-pi / 2) self.point_set.add_point(north_pole) self.point_set.add_point(south_pole) self.min_discrepancy_distance = 1 / self.point_set.size # In below we get the confidence phi around the north pole highest_phi = -1 for i in range(int(n / 2) - 1, n - 2): phi1 = phis[i] phi2 = phis[i + 1] v1 = array([mpf(0), cos(phi1), mpf(0)]) v2 = array([2 * cos(phi1), mpf(0), sin(phi2) - sin(phi1)]) normal_vector = cross(v1, v2) normal_vector /= norm(normal_vector) highest_phi = max(highest_phi, asin(abs(normal_vector[2]))) return float(highest_phi)
def phiinv(x): return mpmath.asin(mpmath.sqrt(x)) / (2.0 * mpmath.pi)
def m(rx, theta): return mpmath.power( mpmath.sin(mpmath.power(2, rx) * mpmath.asin(mpmath.sqrt(theta))), 2)
import mpmath as math from units import * from copy import copy def sqrt(x): if hasattr(x,'unit'): return math.sqrt(x.number) | x.unit**0.5 return math.sqrt(x) #trigonometric convenience functions which are "unit aware" sin=lambda x: math.sin(1.*x) cos=lambda x: math.cos(1.*x) tan=lambda x: math.tan(1.*x) cot=lambda x: math.cot(1.*x) asin=lambda x: math.asin(x) | rad acos=lambda x: math.acos(x) | rad atan=lambda x: math.atan(x) | rad atan2=lambda x,y: math.atan2(x,y) | rad #~ cos=math.cos #~ sin=math.sin #~ tan=math.tan #~ cosh=math.cosh #~ sinh=math.sinh #~ tanh=math.tanh #~ acos=math.acos #~ asin=math.asin #~ atan=math.atan acosh=math.acosh asinh=math.asinh
'cbrt': ['primitive', [lambda x, y: mp.cbrt(x), None]], 'root': ['primitive', [lambda x, y: mp.root(x, y[0]), None]], # y's root 'unitroots': ['primitive', [lambda x, y: Vector(mp.unitroots(x)), None]], # 'hypot': ['primitive', [lambda x, y: mp.hypot(x, y[0]), None]], # sqrt(x**2+y**2) # 'sin': ['primitive', [lambda x, y: mp.sin(x), None]], 'cos': ['primitive', [lambda x, y: mp.cos(x), None]], 'tan': ['primitive', [lambda x, y: mp.tan(x), None]], 'sinpi': ['primitive', [lambda x, y: mp.sinpi(x), None]], #sin(x * pi) 'cospi': ['primitive', [lambda x, y: mp.cospi(x), None]], 'sec': ['primitive', [lambda x, y: mp.sec(x), None]], 'csc': ['primitive', [lambda x, y: mp.csc(x), None]], 'cot': ['primitive', [lambda x, y: mp.cot(x), None]], 'asin': ['primitive', [lambda x, y: mp.asin(x), None]], 'acos': ['primitive', [lambda x, y: mp.acos(x), None]], 'atan': ['primitive', [lambda x, y: mp.atan(x), None]], 'atan2': ['primitive', [lambda x, y: mp.atan2(y[0], x), None]], 'asec': ['primitive', [lambda x, y: mp.asec(x), None]], 'acsc': ['primitive', [lambda x, y: mp.acsc(x), None]], 'acot': ['primitive', [lambda x, y: mp.acot(x), None]], 'sinc': ['primitive', [lambda x, y: mp.sinc(x), None]], 'sincpi': ['primitive', [lambda x, y: mp.sincpi(x), None]], 'degrees': ['primitive', [lambda x, y: mp.degrees(x), None]], #radian - >degree 'radians': ['primitive', [lambda x, y: mp.radians(x), None]], #degree - >radian # 'exp': ['primitive', [lambda x, y: mp.exp(x), None]], 'expj': ['primitive', [lambda x, y: mp.expj(x), None]], #exp(x*i)
def get_angle_delta(self): if mpmath.almosteq(self.getUncertainty(), 1, epsilon): return mpmath.mpf("0") else: return mpmath.asin(self.getBelief() / self.get_length_to_uncertainty())
def asin(op): expr = mpmath.asin(op) return convertFromRadians(expr)
# ------------------------------------------------------ # Now the actual code # ------------------------------------------------------ # make this a command line input parameter so it can be set # automatically based on the legth of the points array #r = 8 # 2^{-r} is our precision # concatenate the first r bits of each phiinv(y) to omega represented as a string (omegastr) omegastr = "" for n, x, y in points: omegastr += float2binary(phiinv(y))[:r] print("Omega = ", omegastr) omega = binary2float(omegastr) # convert omega to a mp real theta = phi(omega) # compute theta print("Theta = ", theta) m.asin_sqrt_theta = mpmath.asin( mpmath.sqrt(theta)) # IK: needs to be computed only once # now run the model to recover, print the fitted values for n, x, y in points: ymodel = m(r * n, theta) # these fitted values may then be plotted print(x, y, float(ymodel))
def eval(self, z): return mpmath.asin(z)
def arcsin_degrees(x): """Return arcsine of x in degrees.""" return normalized_degrees_from_radians(asin(x))
def zeta_r(_P: float, r: float, M: float) -> float: """Calculate the elliptic integral argument Zeta_r for a given value of P and r""" Qvar = Q(_P, M) a = (Qvar - _P + 2 * M + (4 * M * _P) / r) / (Qvar - _P + (6 * M)) s = mpmath.asin(mpmath.sqrt(a)) return s
def ft(x): return mpmath.asin(x)
def zeta_inf(_P: float, M: float, tol: float = 1e-6) -> float: """Calculate Zeta_inf for elliptic integral F(Zeta_inf, k)""" Qvar = Q(_P, M) # Q variable, only call to function once arg = (Qvar - _P + 2 * M) / (Qvar - _P + 6 * M) z_inf = mpmath.asin(mpmath.sqrt(arg)) return z_inf
def is_discrepancy_less_than(self, d, highest_phi=None, lowest_phi=0, first_theta=0, last_theta=None, dtheta_method='dynamic'): from math import pi, asin from time import time start = time() if highest_phi: self.highest_phi = highest_phi else: self.highest_phi = pi / 2 if last_theta: self.last_theta = last_theta else: self.last_theta = 2 * pi self.lowest_phi = lowest_phi self.first_theta = first_theta phi_check = 0 <= self.lowest_phi and self.lowest_phi < self.highest_phi and self.highest_phi <= pi / 2 if not phi_check: print("There is an issue in phi constrains") return False theta_check = 0 <= self.first_theta and self.first_theta < self.last_theta and self.last_theta <= 2 * pi if not theta_check: print("There is an issue in theta constrains") return False self.reset_discrepancy_parameters() self.is_complete_orbit = (self.first_theta == 0) and (self.last_theta == 2 * pi) self.checked_discrepancy_upper_bound = d # making directions file title = [ "x", "y", "z", "theta", "phi", "norm", "discrepancy", "conf. r", "covered radius", "covering type" ] self.write_title(title_list=title, file_address=self.directions_file_address) # making cover cap file title = [] self.write_title(title_list=title, file_address=self.cover_cap_file_address) # making orbit file title = [ "phi", "expected radius", "dtheta", "covered phi", "fd", "ld", "#d" ] self.write_title(title_list=title, file_address=self.orbits_file_address, is_orbit_file=True) if self.highest_phi == pi / 2: could_add = self.add_direction(theta=0, phi=pi / 2, d=d, expected_radius=0) # We can put a positive expected radius if not could_add: print("The algorithm cannot handle the north pole!") return False else: confidence_r = self.directions[0].confidence_radius covered_phi = asin(r_to_dot(confidence_r)) else: covered_phi = self.highest_phi while covered_phi > self.lowest_phi: phi, expected_radius, mindtheta = self.get_phi_expected_r_dtheta( d=d, covered_phi=covered_phi) # if expected_radius is 0 we should stop, or do something if expected_radius == 0: self.write_report(start=start, is_covered=False) return False theta = self.first_theta minind = self.direction_number + 1 should_continue = True while should_continue: could_add = self.add_direction(theta=theta, phi=phi, d=d, expected_radius=expected_radius) if not could_add: last_direction, discrepancy, projection = self.create_direction( theta=theta, phi=phi) cr = self.get_confidence_radius(d=d, discrepancy=discrepancy, projection=projection) last_direction.directional_discrepancy = discrepancy last_direction.confidence_radius = cr self.write_report(start=start, is_covered=False, found_higher_disrepancy=True) return False direction = self.directions[-1] dtheta = self.get_dtheta(direction=direction, mindtheta=mindtheta, dtheta_method=dtheta_method) # The below lets the cover go one direction after last_theta if the orbit is not complete if not self.is_complete_orbit: should_continue = theta < self.last_theta theta += dtheta if self.is_complete_orbit: should_continue = theta < self.last_theta self.orbits_number += 1 maxind = self.direction_number covered_phi = self.get_covered_phi(minind=minind, maxind=maxind, phi=phi, dtheta=dtheta, dtheta_method=dtheta_method) self.write_orbit_data(phi=phi, expected_r=expected_radius, dtheta=dtheta, minind=minind, maxind=maxind, coveredphi=covered_phi) cover_cap_index_file_add = self.output_folder + "cover_cap_indices.txt" first_round_run_time = time() - start cover_cap_start = time() answer = True not_covered_with_cover_cap = [] for ind in self.not_covered_directions: direction = self.directions[ind] could_cover, found_higher_discrepancy, calls_num = self.cover_cap( direction) if found_higher_discrepancy: self.write_report(start=start, is_covered=False, found_higher_disrepancy=True) return False elif not could_cover: answer = False not_covered_with_cover_cap += [ind] self.calls_list.append(calls_num) cover_cap_run_time = time() - cover_cap_start cover_cap_ind = open(cover_cap_index_file_add, mode="w+", buffering=1) cover_cap_ind.write("number\t" + "direction_ind\t" + "# of covercap\t\n") for i in range(len(self.not_covered_directions)): cover_cap_ind.write( str(i) + "\t" + str(self.not_covered_directions[i]) + "\t" + str(self.calls_list[i]) + "\t\n") cover_cap_ind.close() if not answer: issue_file_add = self.output_folder + "not_covered_directions.txt" file = open(issue_file_add, "w+") file.write("The following directions could not be covered\n") file.close() write_comma_separated(List=not_covered_with_cover_cap, address=issue_file_add) self.write_report(start=start, is_covered=answer, problematic_directions=not_covered_with_cover_cap, first_round_run_time=first_round_run_time, cover_cap_run_time=cover_cap_run_time) return answer