def visibility_first_derivative(self, posix_time): """Calculate the derivative of the visibility function of the satellite and the site at a given time. Args: posix_time (float): The UNIX time to evaluate the derivative visibility function at. Returns: The value of the visibility function evaluated at the provided time. """ # Since most helper functions don't play well with mpmath floats we have to perform a lossy # conversion. posix_time = float(posix_time) sat_pos_vel = np.array( self.sat_irp.interpolate(posix_time)) * mp.mpf(1.0) site_pos = np.array(self.site_ecef) * mp.mpf(1.0) pos_diff = np.subtract(sat_pos_vel[0], site_pos) vel_diff = sat_pos_vel[1] site_normal_pos = site_pos / mp.norm(site_pos) site_normal_vel = [0, 0, 0] first_term = mp.mpf( ((1.0 / mp.norm(pos_diff)) * (mp.fdot(vel_diff, site_normal_pos) + mp.fdot(pos_diff, site_normal_vel)))) second_term = mp.mpf(((1.0 / mp.power( (mp.norm(pos_diff)), 3)) * mp.fdot(pos_diff, vel_diff) * mp.fdot(pos_diff, site_normal_pos))) return first_term - second_term
def rotate_mp(pts, x, y): out = mpm.zeros(pts.rows, pts.cols) v = x/mpm.norm(x) cos = mpm.fdot(x,y) / (mpm.norm(x), mpm.norm(y)) sin = mpm.sqrt(1.-cos**2) u = y - mpm.fdot(v, y) * v mat = mpm.eye(x.cols) - u.T * u - v.T * v \ + cos * u.T * u - sin * v.T * u + sin * u.T * v + cos * v.T * v return mat
def poincare_reflect(a, x, c=1.0, precision=None): ''' Spherical inversion (or "Poincare reflection") of a point x about a sphere with center at point "a", and radius = 1/c. ''' if precision is not None: mpm.mp.dps = precision a2 = mpm.fdot(a, a) x2 = mpm.fdot(x, x) xa2 = x2 + a2 - 2 * mpm.fdot(x, a) r2 = a2 - 1. / c scal = mpm.fdiv(r2, xa2) return scal * (x - a) + a
def rotate_3D_mp(x, y): xnorm = mpm.norm(x) ynorm = mpm.norm(y) cos = mpm.fdot(x,y)/(xnorm*ynorm) sin = mpm.sqrt(1.-cos**2) K = (y.T*x-x.T*y)/(xnorm*ynorm*sin) return mpm.eye(3) + sin*K + (1.-cos)*(K*K)
def poincare_reflect0(z, x, c=1.0, precision=None): ''' Spherical inversion (or "Poincare reflection") of a point x such that point z is mapped to the origin. ''' if precision is not None: mpm.mp.dps = precision # the reflection is poincare_reflect(a, x) where # a = c * z / |z|**2 z2 = mpm.fdot(z, z) zscal = c / z2 x2 = mpm.fdot(x, x) a2 = c * zscal r2 = a2 - 1. / c xa2 = x2 + a2 - 2 * zscal * mpm.fdot(z, x) scal = mpm.fdiv(r2, xa2) return scal * (x - zscal * z) + zscal * z
def myfunction(M): """ sum of matrix elements """ if isinstance(M, np.ndarray): return sum(sum(M)) else: assert isinstance(M, (mp.iv.matrix)), "type {}".format(type(M)) return mp.fdot(M, mp.iv.ones(len(M)))
def __div__(self, B): if self.onlyNP == True and (type(B) == int or type(B) == float): return Matrix(np.divide(self.NP, B).tolist(), onlyNP=True) elif self.onlyNP == True and (type(B) == int or isinstance(B, np.float64)): return Matrix(np.divide(self.NP, B).tolist(), onlyNP=True) elif self.onlyNP == True and (type(B) == int or type(B) == float): f = mpmath.fraction(1, B) return Matrix(mpmath.fdot(self.MP, f).tolist(), onlyMP=True)
def poincare_dist(x, y, c=1.0, precision=None): ''' The hyperbolic distance between points in the Poincare model with curvature -1/c Args: x, y: size 1xD mpmath matrix representing point in the D-dimensional ball |x| < 1 precision (int): bits of precision to use Returns: mpmath float object. Can be converted back to regular float ''' if precision is not None: mpm.mp.dps = precision x2 = mpm.fdot(x, x) y2 = mpm.fdot(y, y) xy = mpm.fdot(x, y) sqrt_c = mpm.sqrt(c) denom = 1 - 2 * c * xy + c**2 * x2 * y2 norm = mpm.norm( (-(1 - 2 * c * xy + c * y2) * x + (1. - c * x2) * y) / denom) return 2 / sqrt_c * mpm.atanh(sqrt_c * norm)
def psi(t, eigenvalues, coefficients, f0=mp.mpf("1.0")): '''The nearly periodic function''' f = None if len(eigenvalues) == len(coefficients): f = [mp.expj(E*t) for E in eigenvalues] f = mp.fdot(coefficients, f) f = mp.fabs(f - f0) return(f)
def point_plane_distance(self, point: Point): ''' calculates point distance from the plane :param point: list or numpy array :return: err, distance distance = (a*x0 + b*y0 + c*z0 + d)/ sqrt(a**2 + b**2 + c**2) ''' numerator = mpmath.fdot(self.abcd, HmPoint.from_point(point).xyzw) denominator = mpmath.sqrt(self.nv.dot(self.nv)) distance = numerator / denominator return distance
def visibility(self, posix_time): """Calculate the visibility function of the satellite and the site at a given time. Args: posix_time (float): The time to evaluate the visibility function at Returns: The value of the visibility function evaluated at the provided time. Note: This function assumes the FOV of the sensors on the satellite are 180 degrees """ # Since most helper functions don't play well with mpmath floats we have to perform a lossy # conversion. posix_time = float(posix_time) site_pos = np.array(self.site_ecef) * mp.mpf(1.0) site_normal_pos = site_pos / mp.norm(site_pos) sat_pos = self.sat_irp.interpolate(posix_time)[0] sat_site = np.subtract(sat_pos, site_pos) return mp.mpf(mp.fdot(sat_site, site_normal_pos) / mp.norm(sat_site))
def remezStep(self, control): # eval at control points fxn = mp.matrix([self.evalFunc(c) for c in control]) # create linear system with chebyshev polynomials size = self.order + 2 system = mp.zeros(size) for n in range(self.order + 1): for i in range(self.order + 2): system[i, n] = mp.chebyt(n, control[i]) # last column is oscillating error for i in range(size): sign = -1 if ((i & 1) == 0) else +1 scale = 0.0 if i in [0, size - 1] else 1.0 system[i, size - 1] = sign * scale * mp.fabs(self.evalWeight(control[i])) #print(system) # solve the system solved = system**-1 #print(solved) # compute polynomial estimate (as Chebyshev weights) weights = vzeros(size - 1) for n in range(size - 1): weights[n] = mp.fdot(solved[n, :], fxn) #print(f' weights: {weights}') # estimate error # self.weights = weights # est = [self.evalEstimate(x) for x in control] # print(' est:', est) # print(' fxn:', fxn.T) return weights
def __mul__(self, B): #print(type(B)) if type(B) == float or type(B) == int or type(B) == np.float64 or type( B) == np.complex128: if self.onlyNP == True: return Matrix(np.dot(self.NP, B).tolist(), onlyNP=True) elif self.Sparse == True: return Matrix(self.S * B, Sparse=True) elif self.onlyNP == True and B.onlyNP == True: if (type(np.dot(self.NP, B.NP).tolist()) == float or type(np.dot(self.NP, B.NP).tolist()) == int): return (np.dot(self.NP, B.NP).tolist()) else: return Matrix(np.dot(self.NP, B.NP).tolist(), onlyNP=True) elif self.onlyMP == True and B.onlyMP == True: return Matrix(mpmath.fdot(self.MP, B.MP).tolist(), onlyMP=True) elif self.Sparse == True and B.Sparse == True: #print(self.S.shape) #print(B.S.shape) M = self.S * B.S if M.shape == (1, 1): return float(M.todense()) else: return Matrix(self.S * B.S, Sparse=True)
def initRemez(self): #print('Remez.init()') # constants for domain (xMin, xMax) = self.domain self.k1 = (xMax + xMin) * 0.5 self.k2 = (xMax - xMin) * 0.5 # initial estimates for function roots (where error == 0.0) size = self.order + 1 roots = vzeros(size) fxn = vzeros(size) # \todo [petri] use linspace for i in range(size): roots[i] = (2.0 * i - self.order) / size fxn[i] = self.evalFunc(roots[i]) # build matrix of Chebyshev evaluations system = mp.zeros(size) for order in range(size): for i in range(size): system[i, order] = mp.chebyt(order, roots[i]) # solve system solved = system**-1 # compute Chebyshev weights of new approximation weights = vzeros(size) for n in range(size): weights[n] = mp.fdot(solved[n, :], fxn) #print(f' weights: {weights.T}') # store roots & weights self.roots = roots self.weights = weights self.maxError = 1000.0
def dot(self, other_vector): return mpmath.fdot(self.abc, other_vector.abc)
def magnitude(self): p = mpmath.fdot(self.abc, self.abc) return mpmath.sqrt(p)
def dot(self, other_vector): return mpmath.fdot(self.xyzw, other_vector.xyzw)