def orientate(self): """Orientate the character towards the current destination. """ direction = self[Movable].direction if direction: dx = direction.x dy = direction.y if dx: target_heading = atan(dy / dx) + (pi / 2) * copysign(1, dx) else: target_heading = pi if dy > 0 else 0 # Compute remaining rotation delta = target_heading - self.heading abs_delta = abs(delta) if abs_delta > WHOLE_ANGLE / 2: abs_delta = WHOLE_ANGLE - abs(delta) delta = -delta # tweak speed (XXX: make it more rational) rot_speed = abs_delta * 2 * pi / 40 if abs_delta < rot_speed * 2: # Rotation is complete within a small error. # Force it to the exact value: self.heading = target_heading return self.heading += copysign(1, delta) * rot_speed # normalize angle to be in (-pi, pi) if self.heading >= WHOLE_ANGLE / 2: self.heading = -WHOLE_ANGLE + self.heading if self.heading < -WHOLE_ANGLE / 2: self.heading = WHOLE_ANGLE + self.heading
def deflectionTo(self, otherPt, preferredDir=None): '''When interpreting both ExtendedPoints as Vectors, return the deflection (in units of radians). Negative deflection is left. :param otherPt: ExtendedPoint to be compared with for computation of deflection :param longSolution: if True, compute deflection the long way around the circle :return: a namedTuple of the interior solution azimuth and the exterior solution azimuth :rtype: namedTuple AzimuthPair ''' defl = otherPt.azimuth - self.azimuth if defl < -1.0 * math.pi: interiorDeflection = defl + 2 * math.pi exteriorDeflection = defl elif defl > math.pi: interiorDeflection = defl - 2 * math.pi exteriorDeflection = defl else: interiorDeflection = defl if defl > 0.0: exteriorDeflection = defl - 2 * math.pi else: exteriorDeflection = defl + 2 * math.pi if preferredDir == None: return AzimuthPair(interiorSolution = interiorDeflection, exteriorSolution = exteriorDeflection) elif math.copysign(1, exteriorDeflection) == math.copysign(1, preferredDir): return exteriorDeflection return interiorDeflection
def updatePlayerDirectionOnCollision(self): scale = 1.2 #moves players away from each other by this factor xDirection = -self.velocity*math.cos(self.angle) yDirection = -self.velocity*math.sin(self.angle) xDirection = math.copysign(math.ceil(abs(xDirection)), xDirection) yDirection = math.copysign(math.ceil(abs(yDirection)), yDirection) self.move(xDirection*scale, yDirection*scale)
def write_corner(fhandler, r, n, last_id, m_fact=1.0): """Write the Ghost particles as well as the common mirror particle, for a corner. This method is only for convex bodies, and Ghost particles. Position arguments: r -- Mirroring position n -- Outward normal of the corner last_id -- Number of already written particles Keyword arguments: m_fact -- Mass multiplier factor (To eventually overlap ghost particles) Returned value: Number of written particles """ if BC != 'GP': return 0 n_box = 1 write_particle(fhandler, r, n=n, mass=dr, imove=-2) dir = (math.copysign(1.0, n[0]), math.copysign(1.0, n[1])) dx = 0.5 * dr while dx < sep * h: x = r[0] + dir[0] * dx dy = 0.5 * dr while dy < sep * h: y = r[1] + dir[1] * dy write_particle(fhandler, (x, y), n=n, mass=m_fact*refd*dr**2, imove=-1, associated=last_id) n_box += 1 dy += dr dx += dr return n_box
def apply_matching(self,error_type,matching): """ applies appropriate flips to the array to bring it back to the codespace using the given matching """ channel=0 if error_type=="X" else 1 flips=[] for pair in matching: [p0,p1]=pair[0] [q0,q1]=pair[1] if channel==1 and (p1==-1 or p1==self.size*2+1)and(q1==-1 or q1==self.size*2+1): flips+=[] elif channel==0 and (p0==-1 or p0==self.size*2+1)and(q0==-1 or q0==self.size*2+1): flips+=[] else: s0=int(math.copysign(1,q0-p0)) s1=int(math.copysign(1,q1-p1)) range0=range(1,abs(q0-p0),2) range1=range(1,abs(q1-p1),2) for x in range1: flips+=[[p0,p1+s1*x]] for y in range0: flips+=[[p0+s0*y,q1]] for flip in flips: self.array[flip[0]][flip[1]][channel]*=-1
def repulsiveFields(self, x=-1, y=-1): if x != -1 and y != -1: self.currentTank.x = x self.currentTank.y = y radius = 5; spread = 10; beta = 20; if self.currentTank.flag != '-': return for tank in self.mytanks: if tank is self.currentTank: continue distance = math.sqrt(math.pow(tank.x - self.currentTank.x, 2) + math.pow(self.currentTank.y - tank.y, 2)) angle = self.normalize_angle(math.atan2(tank.y - self.currentTank.y, tank.x - self.currentTank.x)) if distance < radius: doX = math.copysign(1, math.cos(angle)) * -9001 doY = math.copysign(1, math.sin(angle)) * -9001 elif radius <= distance and distance <= (spread + radius): doX = -beta * (spread + radius - distance) * math.cos(angle) doY = -beta * (spread + radius - distance) * math.sin(angle) else: doX = 0; doY = 0; self.dx = self.dx + doX self.dy = self.dy + doY
def assertFloatsAreIdentical(self, x, y): """assert that floats x and y are identical, in the sense that: (1) both x and y are nans, or (2) both x and y are infinities, with the same sign, or (3) both x and y are zeros, with the same sign, or (4) x and y are both finite and nonzero, and x == y """ msg = 'floats {!r} and {!r} are not identical' if isnan(x) or isnan(y): if isnan(x) and isnan(y): return elif x == y: if x != 0.0: return # both zero; check that signs match elif copysign(1.0, x) == copysign(1.0, y): return else: msg += ': zeros have different signs' if test_support.due_to_ironpython_bug("http://ironpython.codeplex.com/workitem/28352"): print msg.format(x, y) return self.fail(msg.format(x, y))
def assert_same_sign(a, b, fp_zero=1e-9): if (a == sp.NaN) or (b == sp.NaN): raise ValueError("NaN(s) passed to sign comparison functions") elif (abs(a) < fp_zero) and (abs(b) < fp_zero): assert True else: assert math.copysign(1, a) == math.copysign(1, b)
def scrollEvent(self, dx=0, dy=0): """ Generate scroll events from parametters and displacement @param int dx delta movement from last call on x axis @param int dy delta movement from last call on y axis @param bool free set to true for free ball move @return float absolute distance moved this tick """ # Compute mouse mouvement from interger part of d * scale self._scr_dx += dx * self._scr_xscale self._scr_dy += dy * self._scr_yscale _syn = False if int(self._scr_dx): self.relEvent(rel=Rels.REL_HWHEEL, val=int(copysign(1, self._scr_dx))) self._scr_dx -= int(self._scr_dx) _syn = True if int(self._scr_dy): self.relEvent(rel=Rels.REL_WHEEL, val=int(copysign(1, self._scr_dy))) self._scr_dy -= int(self._scr_dy) _syn = True if _syn: self.synEvent()
def getTangentialField(self, tank, obstacle): obstacle_x = (obstacle[0][0] + obstacle[2][0])/2 obstacle_y = (obstacle[0][1] + obstacle[2][1])/2 dx = abs(obstacle_x - tank.x) dy = abs(obstacle_y - tank.y) distance = math.sqrt((obstacle[2][0]-obstacle[0][0])**2 + (obstacle[2][1]-obstacle[0][1])**2) radius = distance/2 #flag radius spread = radius + 20 #spread beta = 3.6 a = math.atan2(obstacle_y - tank.y, obstacle_x - tank.x) d = math.sqrt(dx**2 + dy**2) field = Field() field.angle = a field.magnitude = d if (d < radius): field.dx = - math.copysign(1, math.cos(a + math.pi/4)) * ((1/d) if d > 0 else 10) field.dy = - math.copysign(1, math.sin(a + math.pi/4)) * ((1/d) if d > 0 else 10) elif (radius <= d and d <= spread + radius): field.dx = -beta * (spread + radius - d) * math.cos(a + math.pi/4) field.dy = -beta * (spread + radius - d) * math.sin(a+ math.pi/4) elif (d > spread + radius): field.dx = 0 field.dy = 0 return field
def move_vector(self): #horizontal? if self.x_real == self.x_dest: self.x_move = 0 #up by default self.y_move = 1 #whoops, we need down if(self.y_dest < self.y_real): self.y_move = -1 #negative safely unreald slope self.m = (-999,1) #positive safely unreal slope else: self.m = (999,1) #we have vertical movement, find slope else: self.m = ((self.y_dest - self.y_real), (self.x_dest - self.x_real)) self.y_move = self.m[0]/(abs(self.m[0])+abs(self.m[1])) self.x_move = 1 - self.y_move #make sure the sign is correct self.y_move = math.copysign(self.y_move, self.m[0]) self.x_move = math.copysign(self.x_move, self.m[1])
def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323): """Determine whether floating-point values a and b are equal to within a (small) rounding error. The default values for rel_err and abs_err are chosen to be suitable for platforms where a float is represented by an IEEE 754 double. They allow an error of between 9 and 19 ulps.""" # special values testing if math.isnan(a): return math.isnan(b) if math.isinf(a): return a == b # if both a and b are zero, check whether they have the same sign # (in theory there are examples where it would be legitimate for a # and b to have opposite signs; in practice these hardly ever # occur). if not a and not b: return math.copysign(1., a) == math.copysign(1., b) # if a-b overflows, or b is infinite, return False. Again, in # theory there are examples where a is within a few ulps of the # max representable float, and then b could legitimately be # infinite. In practice these examples are rare. try: absolute_error = abs(b-a) except OverflowError: return False else: return absolute_error <= max(abs_err, rel_err * abs(a))
def squashMatching(size,error_type,matching): channel=0 if error_type=="X" else 1 flip_array=[[1]*(2*size+1) for _ in range(2*size+1)] for [(pt,p0,p1),(qt,q0,q1)] in matching: flips = [] if (p0 in [-1,size*2+1] and q0 in [-1,size*2+1]) or (p1 in [-1,size*2+1] and q1 in [-1,size*2+1]): flips+=[] else: s0=int(math.copysign(1,q0-p0)) s1=int(math.copysign(1,q1-p1)) range0=range(1,abs(q0-p0),2) range1=range(1,abs(q1-p1),2) for x in range1: flips+=[[p0,p1+s1*x]] for y in range0: flips+=[[p0+s0*y,q1]] for flip in flips: flip_array[flip[0]][flip[1]]*=-1 return flip_array
def GetXYZ(self): """Returns angles (theta,phi,psi) for: an x-rotation by theta followed by a y-rotation by phi followed by a z-rotation by psi. Active rotations are considered here. This works in all quadrants Note that if you construct a rotation matrix using three angles, you may not get back the same angles from this function (i.e. the mapping between xyz-angle-triples and SO(3) is not 1-1)""" phi=math.asin(-self.item(2,0)) if math.fabs(1.-math.fabs(self.item(2,0)))>.0000001: # if the phi rotation is not by pi/2 or -pi/2 (two solutions, return one of them) psi=math.atan2(self.item(1,0),self.item(0,0)) theta=math.atan2(self.item(2,1),self.item(2,2)) else: # if the phi rotation was in fact by pi/2 or -pi/2 (infinite solutions- pick 0 for psi and solve for theta) psi=0 if math.fabs(self.item(1,1))>.0000001 and math.fabs(self.item(0,2))>.0000001: #as long as these matrix elements aren't 0 if math.copysign(1,self.item(1,1))==math.copysign(1,self.item(0,2)): # relative sign of these matrix elements determines theta's quadrant theta=math.atan2(self.item(0,1),self.item(1,1)) else: theta=math.atan2(-self.item(0,1),self.item(1,1)) else: # if one of them was zero then use these matrix elements to test for theta's quadrant instead if not math.copysign(1,self.item(0,1))==math.copysign(1,self.item(1,2)): # relative sign of these matrix elements determines theta's quadrant theta=math.atan2(self.item(0,1),self.item(1,1)) else: theta=math.atan2(-self.item(0,1),self.item(1,1)) return (theta,phi,psi)
def readline(self): if self.readList is None: return '' n = 0 timeDiff = self.lastTempAt - time.time() self.lastTempAt = time.time() if abs(self.temp - self.targetTemp) > 1: self.temp += math.copysign(timeDiff * 10, self.targetTemp - self.temp) if self.temp < 0: self.temp = 0 if abs(self.bedTemp - self.bedTargetTemp) > 1: self.bedTemp += math.copysign(timeDiff * 10, self.bedTargetTemp - self.bedTemp) if self.bedTemp < 0: self.bedTemp = 0 while len(self.readList) < 1: time.sleep(0.1) n += 1 if n == 20: return '' if self.readList is None: return '' time.sleep(0.001) return self.readList.pop(0)
def update(self): print(self.children) self.map_offset = self.parent.offset if copysign(1, self.velocity[0]) * (self.touch_position[0] - self.map_position[0]) < 0: self.velocity[0] = 0 if copysign(1, self.velocity[1]) * (self.touch_position[1] - self.map_position[1]) < 0: self.velocity[1] = 0 if not self.parent.collide_point(self.map_position[0],self.map_position[1]): self.map_position[0] -= self.velocity[0] self.map_position[1] -= self.velocity[1] self.velocity = [0,0] for child in self.parent.children: if child.id == self.id or child.id == 'sprite': continue if self.collide_widget(child): self.map_position[0] -= self.velocity[0] self.map_position[1] -= self.velocity[1] self.velocity = [0,0] print(self.id,child.id,self.collide_widget(child)) self.map_position[0] += self.velocity[0] self.map_position[1] += self.velocity[1] self.x = self.map_position[0] + self.map_offset[0] self.y = self.map_position[1] + self.map_offset[1] # print(self.parent.children[0].map_position) # print(self.collide_widget(self.parent.children[0])) return
def GetG4XYZ(self): """Returns angles (theta,phi,psi) for: an x-rotation by theta followed by a y-rotation by phi followed by a z-rotation by psi. Passive rotations are considered here, as expected for a GEANT4 rotation. That is equivalent to an Active rotation by -psi,-phi,-theta in the ZYX order. Note that this is the same algorithm as GetXYZ(), for the INVERSE matrix. This works in all quadrants Note that if you construct a rotation matrix using three angles, you may not get back the same angles from this function (i.e. the mapping between xyz-angle-triples and SO(3) is not 1-1)""" phi= -math.asin(self.item(0,2)) if math.fabs(1.-math.fabs(self.item(0,2))) > 0.0000001: psi = math.atan2(self.item(0,1),self.item(0,0)) theta= math.atan2(self.item(1,2),self.item(2,2)) else: psi = 0 if math.fabs(self.item(1,1)) > 0.0000001 and math.fabs(self.item(2,0))>0.0000001: if math.copysign(1,self.item(1,1)) == math.copysign(1,self.item(2,0)): theta=math.atan2(self.item(1,0),self.item(1,1)) else: theta=math.atan2(-self.item(1,0),self.item(1,1)) else: if not math.copysign(1,self.item(1,0)) == math.copysign(1,self.item(2,1)): theta=math.atan2(self.item(1,0),self.item(1,1)) else: theta=math.atan2(-self.item(1,0),self.item(1,1)) return(theta,phi,psi)
def _roll(cls, start_x, start_y, finish_x, finish_y): path = [] x = start_x y = start_y if math.fabs(finish_x - start_x) > math.fabs(finish_y - start_y): dx = math.copysign(1.0, finish_x - start_x) dy = dx * float(finish_y - start_y) / (finish_x - start_x) else: dy = math.copysign(1.0, finish_y - start_y) dx = dy * float(finish_x - start_x) / (finish_y - start_y) real_x = float(x) real_y = float(y) while x != finish_x or y != finish_y: real_x += dx real_y += dy if int(round(real_x)) == x + 1: path.append(PATH_DIRECTION.RIGHT.value) elif int(round(real_x)) == x - 1: path.append(PATH_DIRECTION.LEFT.value) if int(round(real_y)) == y + 1: path.append(PATH_DIRECTION.DOWN.value) elif int(round(real_y)) == y - 1: path.append(PATH_DIRECTION.UP.value) x = int(round(real_x)) y = int(round(real_y)) return ''.join(path)
def float_round(value, precision_digits=None, precision_rounding=None, rounding_method='HALF-UP'): """Return ``value`` rounded to ``precision_digits`` decimal digits, minimizing IEEE-754 floating point representation errors, and applying the tie-breaking rule selected with ``rounding_method``, by default HALF-UP (away from zero). Precision must be given by ``precision_digits`` or ``precision_rounding``, not both! :param float value: the value to round :param int precision_digits: number of fractional digits to round to. :param float precision_rounding: decimal number representing the minimum non-zero value at the desired precision (for example, 0.01 for a 2-digit precision). :param rounding_method: the rounding method used: 'HALF-UP' or 'UP', the first one rounding up to the closest number with the rule that number>=0.5 is rounded up to 1, and the latest one always rounding up. :return: rounded float """ rounding_factor = _float_check_precision(precision_digits=precision_digits, precision_rounding=precision_rounding) if rounding_factor == 0 or value == 0: return 0.0 # NORMALIZE - ROUND - DENORMALIZE # In order to easily support rounding to arbitrary 'steps' (e.g. coin values), # we normalize the value before rounding it as an integer, and de-normalize # after rounding: e.g. float_round(1.3, precision_rounding=.5) == 1.5 # TIE-BREAKING: HALF-UP (for normal rounding) # We want to apply HALF-UP tie-breaking rules, i.e. 0.5 rounds away from 0. # Due to IEE754 float/double representation limits, the approximation of the # real value may be slightly below the tie limit, resulting in an error of # 1 unit in the last place (ulp) after rounding. # For example 2.675 == 2.6749999999999998. # To correct this, we add a very small epsilon value, scaled to the # the order of magnitude of the value, to tip the tie-break in the right # direction. # Credit: discussion with OpenERP community members on bug 882036 normalized_value = value / rounding_factor # normalize epsilon_magnitude = math.log(abs(normalized_value), 2) epsilon = 2**(epsilon_magnitude-53) if rounding_method == 'HALF-UP': normalized_value += math.copysign(epsilon, normalized_value) rounded_value = round(normalized_value) # round to integer # TIE-BREAKING: UP (for ceiling operations) # When rounding the value up, we instead subtract the epsilon value # as the the approximation of the real value may be slightly *above* the # tie limit, this would result in incorrectly rounding up to the next number # The math.ceil operation is applied on the absolute value in order to # round "away from zero" and not "towards infinity", then the sign is # restored. elif rounding_method == 'UP': sign = math.copysign(1.0, normalized_value) normalized_value -= sign*epsilon rounded_value = math.ceil(abs(normalized_value))*sign # ceil to integer result = rounded_value * rounding_factor # de-normalize return result
def rowJacobian(x, y, drop_data, tolerances): [xP, yP, RP, BP, wP] = drop_data.params # x, y = xy # extract the data points # s_0 = drop_data.s_0 if ((x - xP) * cos(wP) - (y - yP) * sin(wP)) < 0: s_0 = drop_data.s_left else: s_0 = drop_data.s_right # if x < xP: # s_0 = s_left # else: # s_0 = s_right xs, ys, dx_dBs, dy_dBs, e_r, e_z, s_i = minimum_arclength(x, y, s_0, drop_data, tolerances) # functions at s* if ((x - xP) * cos(wP) - (y - yP) * sin(wP)) < 0: drop_data.s_left = s_i else: drop_data.s_right = s_i # e_i = sqrt(e_r**2 + e_z**2) # actual residual e_i = math.copysign(sqrt(e_r**2 + e_z**2), e_r) # actual residual sgnx = math.copysign(1, ((x - xP) * cos(wP) - (y - yP) * sin(wP))) # calculates the sign for ddi_dX0 ddi_dxP = -( e_r * sgnx * cos(wP) + e_z * sin(wP) ) / e_i # derivative w.r.t. X_0 (x at apex) ddi_dyP = -(-e_r * sgnx * sin(wP) + e_z * cos(wP) ) / e_i # derivative w.r.t. Y_0 (y at apex) ddi_dRP = -( e_r * xs + e_z * ys) / e_i # derivative w.r.t. RP (apex radius) ddi_dBP = - RP * (e_r * dx_dBs + e_z * dy_dBs) / e_i # derivative w.r.t. Bo (Bond number) ddi_dwP = (e_r * sgnx * (- (x - xP) * sin(wP) - (y - yP) * cos(wP)) + e_z * ( (x - xP) * cos(wP) - (y - yP) * sin(wP))) / e_i return [[ ddi_dxP, ddi_dyP, ddi_dRP, ddi_dBP, ddi_dwP], e_i]
def glsl_literal(x): """Convert the given number to a string that represents a GLSL literal. :param x: a uint32 or float32 """ if isinstance(x, uint32): return "{0}u".format(uint32(x)) elif isinstance(x, float32): if math.isnan(x): # GLSL ES 3.00 and GLSL 4.10 do not require implementations to # support NaN, so we do not test it. assert(False) elif math.isinf(x): # GLSL ES 3.00 lacks a literal for infinity. However, ±1.0e256 # suffices because it lies sufficientlyoutside the range of finite # float32 values. # # From page 31 of the GLSL ES 3.00 spec: # # If the value of the floating point number is too large (small) # to be stored as a single precision value, it is converted to # positive (negative) infinity. # return repr(copysign(1.0e256, x)) elif x == 0 and copysign(1.0, x) == -1.0: # Workaround for numpy-1.7.0, in which repr(float32(-0.0)) does # not return a float literal. # See https://github.com/numpy/numpy/issues/2935 . return "-0.0" else: return repr(x) else: assert(False)
def VectorMath(ExtPts): aDx = ExtPts[1].X-ExtPts[0].X aDy = ExtPts[1].Y-ExtPts[0].Y bDx = ExtPts[-2].X-ExtPts[0].X bDy = ExtPts[-2].Y-ExtPts[0].Y VectorA=[aDx,aDy] VectorB=[bDx,bDy] VectorX=[1,0] VectorY=[0,1] A_Len = np.linalg.norm(VectorA) B_Len = np.linalg.norm(VectorB) dpAB=dotProduct(VectorA, VectorB) AngAB=math.acos(dpAB/A_Len/B_Len) cpAB=(A_Len*B_Len)*math.sin(AngAB) dpAX=dotProduct(VectorA, VectorX) AngAx=math.acos(dpAX/A_Len/1.0)*math.copysign(1,aDy) dpBX=dotProduct(VectorB, VectorX) AngBx=math.acos(dpBX/B_Len/1.0)*math.copysign(1,bDy) eParts=[A_Len,B_Len, AngAB, AngAx, AngBx,cpAB] return(eParts)
def update(self, txn): if self.sid != txn.sid: raise Exception('updating position with txn for a ' 'different sid') total_shares = self.amount + txn.amount if total_shares == 0: self.cost_basis = 0.0 else: prev_direction = copysign(1, self.amount) txn_direction = copysign(1, txn.amount) if prev_direction != txn_direction: # we're covering a short or closing a position if abs(txn.amount) > abs(self.amount): # we've closed the position and gone short # or covered the short position and gone long self.cost_basis = txn.price else: prev_cost = self.cost_basis * self.amount txn_cost = txn.amount * txn.price total_cost = prev_cost + txn_cost self.cost_basis = total_cost / total_shares # Update the last sale price if txn is # best data we have so far if self.last_sale_date is None or txn.dt > self.last_sale_date: self.last_sale_price = txn.price self.last_sale_date = txn.dt self.amount = total_shares
def intersection_point(center_x, center_y, source_x, source_y, \ width, height=None): """Determines where the rhombus centered at (center_x, center_y) intersects with a line drawn from (source_x, source_y) to (center_x, center_y). @see: ShapeDrawer.intersection_point""" height = height or width if height == 0 and width == 0: return center_x, center_y delta_x, delta_y = source_x - center_x, source_y - center_y # Treat edge case when delta_x = 0 if delta_x == 0: if delta_y == 0: return center_x, center_y else: return center_x, center_y + copysign(height / 2, delta_y) width = copysign(width, delta_x) height = copysign(height, delta_y) f = height / (height + width * delta_y / delta_x) return center_x + f * width / 2, center_y + (1-f) * height / 2
def update_vel(self, delta_time, desired_vel): v = float(desired_vel.v) omega = float(desired_vel.omega) sigma = max(v/self.max_vel, omega/self.max_rot_vel, 1.0) if sigma != 1.0: if v/self.max_vel > omega/self.max_rot_vel: v = copysign(self.max_vel, v) omega /= sigma else: # omega/self.max_rot_vel > v/self.max_vel v /= sigma omega = copysign(self.max_rot_vel, omega) # these are the velocities wheels would get # if they didn't have to accelerate smoothly target_lvel = v - 0.5 * self.width * omega target_rvel = v + 0.5 * self.width * omega if abs(self.lvel - target_lvel) < delta_time * config.BOT_ACCEL_CAP: self.lvel = target_lvel else: self.lvel += copysign(config.BOT_ACCEL_CAP, target_lvel - self.lvel) * delta_time if abs(self.rvel - target_rvel) < delta_time * config.BOT_ACCEL_CAP: self.rvel = target_rvel else: self.rvel += copysign(config.BOT_ACCEL_CAP, target_rvel - self.rvel) * delta_time # cap velocity v = max(abs(self.lvel), abs(self.rvel)) if v > self.max_vel: self.lvel *= self.max_vel / v self.rvel *= self.max_vel / v
def compare(self, flower1, flower2): if (flower1.height == flower2.height): return 0 # never happen if ( self.block(flower1,flower2) ): return int(math.copysign(1, flower1.height - flower2.height)) else: return int(math.copysign(1, flower2.height - flower1.height))
def drag3(event): global x, y, dpx dpx=max(abs(start3[0]-event.x)/sizex,abs(start3[1]-event.y)/sizey) x=start3[0]+copysign(dpx*sizex, event.x-start3[0]) y=start3[1]+copysign(dpx*sizey, event.y-start3[1]) canv.coords(rect,start3[0],start3[1],x,y) canv.itemconfig(rect,state='normal')
def stepThatWay(self): """ Not used. """ fX = self.goal[0] - self.pos.means[0] fY = self.goal[1] - self.pos.means[1] fM = math.hypot(fX, fY) fD = math.atan2(fY, fX) # Convert to robot frame fDR = fD - self.pos.means[2] if math.fabs(fDR) > math.pi: fDR -= math.copysign(2 * math.pi, fDR) if math.fabs(fDR) > math.pi/10.0: provX = 0.0 else: provX = min(self.maxSpeed, self.kSpeed * fM) provZ = math.fabs(self.kTurn * fDR) provZ = min(self.maxTurn, provZ) provZ = math.copysign(provZ, fDR) twist = Twist() twist.linear.x = provX twist.angular.z = provZ return twist
def move_arc(self, radius, theta): turn_speed = 0.0 initial_distance = self.total_distance initial_heading = self.heading arc_length = radius * theta # some calculation while(self.total_distance - initial_distance < abs(arc_length)): turn_speed = 0.0 # calculate desired angle based on distance travelled target_heading = (self.total_distance - initial_distance)/radius target_heading = math.copysign(target_heading, arc_length) # offset by starting angle target_heading += initial_heading # ensure that 0 <= target_heading <= 2*pi if target_heading < 0: target_heading += 2*math.pi if target_heading > 2*math.pi: target_heading -= 2*math.pi error = target_heading - self.heading if error < -math.pi: error += 2*math.pi if error > math.pi: error -= 2*math.pi # correct angle if(abs(error) > 0.008): if abs(error) < 0.05: turn_speed = math.copysign(0.3, error) else: turn_speed = error*5 self.set_speeds(0.2, turn_speed) print "relative distance: ", self.total_distance - initial_distance print "error: ", error self.stop_all_motion() return 1
def update(self, dt): # call parent update (Animation) super().update(dt) # Apply gravity if grounded if not self.grounded: self.velocity_y += self.gravity*dt # Set up vars c_x = self.get_x(); c_y = self.get_y() vx = math.floor(self.velocity_x) vy = math.floor(self.velocity_y) # Collision handling # Collision x while not self.can_move(c_x, c_y, c_x + vx, c_y, 0) and not vx == 0: vx -= math.copysign(1, vx) # Move x self.set_position(c_x + vx, c_y) c_x = self.get_x() # Collision y while not self.can_move(c_x, c_y, c_x, c_y + vy, 1) and not vy == 0: vy -= math.copysign(1, vy) self.velocity_y = 0 # Check if grounded self.grounded = not self.can_move(c_x, c_y, c_x, c_y + 1, 1) # Move y self.set_position(c_x, c_y + vy)
def remainder(x, y): """Difference between x and the closest integer multiple of y. Return x - n*y where n*y is the closest integer multiple of y. In the case where x is exactly halfway between two multiples of y, the nearest even value of n is used. The result is always exact.""" from math import copysign, fabs, fmod, isfinite, isinf, isnan, nan x = float(x) y = float(y) # Deal with most common case first. if isfinite(x) and isfinite(y): if y == 0.0: # return nan # Merging the logic from math_2 in CPython's mathmodule.c # nan returned and x and y both not nan -> domain error raise ValueError("math domain error") absx = fabs(x) absy = fabs(y) m = fmod(absx, absy) # Warning: some subtlety here. What we *want* to know at this point is # whether the remainder m is less than, equal to, or greater than half # of absy. However, we can't do that comparison directly because we # can't be sure that 0.5*absy is representable (the mutiplication # might incur precision loss due to underflow). So instead we compare # m with the complement c = absy - m: m < 0.5*absy if and only if m < # c, and so on. The catch is that absy - m might also not be # representable, but it turns out that it doesn't matter: # - if m > 0.5*absy then absy - m is exactly representable, by # Sterbenz's lemma, so m > c # - if m == 0.5*absy then again absy - m is exactly representable # and m == c # - if m < 0.5*absy then either (i) 0.5*absy is exactly representable, # in which case 0.5*absy < absy - m, so 0.5*absy <= c and hence m < # c, or (ii) absy is tiny, either subnormal or in the lowest normal # binade. Then absy - m is exactly representable and again m < c. c = absy - m if m < c: r = m elif m > c: r = -c else: # Here absx is exactly halfway between two multiples of absy, # and we need to choose the even multiple. x now has the form # absx = n * absy + m # for some integer n (recalling that m = 0.5*absy at this point). # If n is even we want to return m; if n is odd, we need to # return -m. # So # 0.5 * (absx - m) = (n/2) * absy # and now reducing modulo absy gives us: # | m, if n is odd # fmod(0.5 * (absx - m), absy) = | # | 0, if n is even # Now m - 2.0 * fmod(...) gives the desired result: m # if n is even, -m if m is odd. # Note that all steps in fmod(0.5 * (absx - m), absy) # will be computed exactly, with no rounding error # introduced. assert m == c r = m - 2.0 * fmod(0.5 * (absx - m), absy) return copysign(1.0, x) * r # Special values. if isnan(x): return x if isnan(y): return y if isinf(x): # return nan # Merging the logic from math_2 in CPython's mathmodule.c # nan returned and x and y both not nan -> domain error raise ValueError("math domain error") assert isinf(y) return x
def X(b): return copysign(1, b) * sqrt(pi * abs(b)) * Cf(sqrt(abs(b) / pi))
def yCoord(gamma, alpha, s): return gamma * copysign(1, alpha) * sqrt(pi / abs(alpha)) * Sf( sqrt(abs(alpha) / pi) * s)
def _sign(x): return int(copysign(1, x))
def __init__(self): # Give the node a name rospy.init_node('calibrate_linear', anonymous=False) # Set rospy to execute a shutdown function when terminating the script rospy.on_shutdown(self.shutdown) # How fast will we check the odometry values? self.rate = rospy.get_param('~rate', 20) r = rospy.Rate(self.rate) # Set the distance to travel self.test_distance = rospy.get_param('~test_distance', 1.0) # meters self.speed = rospy.get_param('~speed', 0.15) # meters per second self.tolerance = rospy.get_param('~tolerance', 0.01) # meters self.odom_linear_scale_correction = rospy.get_param( '~odom_linear_scale_correction', 1.0) self.start_test = rospy.get_param('~start_test', True) # Publisher to control the robot's speed self.cmd_vel = rospy.Publisher('/cmd_vel', Twist, queue_size=5) # The base frame is base_footprint for the TurtleBot but base_link for Pi Robot self.base_frame = rospy.get_param('~base_frame', '/base_footprint') # The odom frame is usually just /odom #self.odom_frame = rospy.get_param('~odom_frame', '/odom') self.odom_frame = rospy.get_param('~odom_frame', '/odom_combined') # Initialize the tf listener self.tf_listener = tf.TransformListener() # Give tf some time to fill its buffer rospy.sleep(2) # Make sure we see the odom and base frames self.tf_listener.waitForTransform(self.odom_frame, self.base_frame, rospy.Time(), rospy.Duration(60.0)) rospy.loginfo("Bring up rqt_reconfigure to control the test.") self.position = Point() # Get the starting position from the tf transform between the odom and base frames self.position = self.get_position() x_start = self.position.x y_start = self.position.y move_cmd = Twist() while not rospy.is_shutdown(): # Stop the robot by default move_cmd = Twist() if self.start_test: # Get the current position from the tf transform between the odom and base frames self.position = self.get_position() # Compute the Euclidean distance from the target point distance = sqrt( pow((self.position.x - x_start), 2) + pow((self.position.y - y_start), 2)) # Correct the estimated distance by the correction factor distance *= self.odom_linear_scale_correction # How close are we? error = distance - self.test_distance # Are we close enough? if not self.start_test or abs(error) < self.tolerance: self.start_test = False params = {'start_test': False} rospy.loginfo(params) else: # If not, move in the appropriate direction move_cmd.linear.x = copysign(self.speed, -1 * error) else: self.position = self.get_position() x_start = self.position.x y_start = self.position.y self.cmd_vel.publish(move_cmd) r.sleep() # Stop the robot self.cmd_vel.publish(Twist())
def set_cmd_vel(self, msg): global counter counter = 0 try: marker = msg.markers[0] # rospy.loginfo("the Roll is: %d",roll) # rospy.loginfo("the Pitch is: %d",pitch) # rospy.loginfo("the Roll is: %d",yaw) if not self.target_visible: rospy.loginfo("FOLLOWER is Tracking Target!") # quaternion = ( # marker.pose.orientation.x, # marker.pose.orientation.y, # marker.pose.orientation.z, # marker.pose.orientation.w) # euler = tf.transformations.euler_from_quaternion(quaternion) # roll = euler[0] # pitch = euler[1] # yaw = euler[2] #counter+=1 #rospy.loginfo("the frame count is : %f", counter) #print ("Number of succesfully tracked frames so far: %i",counter) self.move_cmd.angular.z = 0.0 self.target_visible = True #rospy.sleep(0.09) nice response except: # If target is lost, stop the robot by slowing it incrementally self.move_cmd.linear.x /= 1.9 #if() self.move_cmd.angular.z = 1.1 if self.target_visible: rospy.loginfo("FOLLOWER LOST Target!") self.target_visible = False counter += 1 return rospy.loginfo("the frame count is : %f", counter) quaternion = (marker.pose.pose.orientation.x, marker.pose.pose.orientation.y, marker.pose.pose.orientation.z, marker.pose.pose.orientation.w) euler = tf.transformations.euler_from_quaternion(quaternion) roll = euler[0] pitch = euler[1] yaw = euler[2] rospy.loginfo("the Roll is: %f", roll) rospy.loginfo("the Pitch is: %f", pitch) rospy.loginfo("the yaw is: %f", yaw) # Get the displacement of the marker relative to the base target_offset_y = marker.pose.pose.position.y # Get the distance of the marker from the base target_offset_x = marker.pose.pose.position.x # Get the distance of the marker from the base target_offset_z = marker.pose.pose.position.z rospy.loginfo("the target_offset_x is: %f", target_offset_x) rospy.loginfo("the target_offset_y is: %f", target_offset_y) rospy.loginfo("the target_offset_z is: %f", target_offset_z) # Rotate the robot only if the displacement of the target exceeds the threshold if abs(target_offset_y) > self.y_threshold: # Set the rotation speed proportional to the displacement of the target speed = (target_offset_y * self.y_scale) self.move_cmd.angular.z = copysign( max(self.min_angular_speed, min(self.max_angular_speed, abs(speed))), speed) else: self.move_cmd.angular.z = 0.0 # Now get the linear speed if (target_offset_x - self.goal_x) > self.x_threshold: speed = abs((self.goal_x - (target_offset_x + 0.2))) * self.x_scale if speed > 0: speed *= 1.5 self.move_cmd.linear.x = copysign( min(self.max_linear_speed, max(self.min_linear_speed, abs(speed))), speed) else: self.move_cmd.linear.x /= 1.9 cspeed = self.move_cmd.linear.x rospy.loginfo("the current speed is : %f", cspeed) if ((target_offset_x <= 0.8) and (target_offset_x >= 0.05) and (cspeed <= 0.1)): self.move_cmd.linear.x = 0.3 # 0.4 worked rospy.loginfo("increasing Speed \n") else: self.move_cmd.linear.x /= 1.01 self.move_cmd.linear.y = 0.0 self.move_cmd.linear.z = 0.0 rospy.loginfo("target achieved\n")
# import math def fail(which): print("fail %s" % which) exit(1) # # Number-theoretic and representation functions # if not math.ceil(0.5) == 1: fail("math.ceil(0.5) == 1") if not math.ceil(-0.5) == 0: fail("math.ceil(-0.5) == 0") if not math.copysign(1.1, -2) == -1.1: fail("math.copysign(1.1, -2) == -1.1") if not math.copysign(-1.1, -2) == -1.1: fail("math.copysign(-1.1, -2) == -1.1") if not math.copysign(1.1, 2) == 1.1: fail("math.copysign(1.1, 2) == 1.1") if not math.copysign(-1.1, 2) == 1.1: fail("math.copysign(-1.1, 2) == 1.1") if not math.fabs(-1.1) == 1.1: fail("math.fabs(-1.1) == 1.1") if not math.fabs(1.1) == 1.1: fail("math.fabs(1.1) == 1.1") if not math.factorial(9) == 362880: fail("math.factorial(9) == 362880") if not math.floor(0.5) == 0: fail("math.floor(0.5) == 0") if not math.floor(-0.5) == -1: fail("math.floor(-0.5) == -1") if not math.frexp(12.5) == (0.78125, 4): fail("math.frexp(12.5) == (0.78125, 4)") if not math.isclose(math.fsum([0.001] * 1000), 1): fail("math.isclose(math.fsum([0.01] * 100), 1)") if not math.gcd(21, 14) == 7: fail("math.gcd(21,14) == 7") big = 10.1 for i in range(40):
def _deriv_copysign(x, y): if x >= 0: return math.copysign(1, y) else: return -math.copysign(1, y)
def testCopysign(self): self.assertEqual(math.copysign(1, 42), 1.0) self.assertEqual(math.copysign(0., 42), 0.0) self.assertEqual(math.copysign(1., -42), -1.0) self.assertEqual(math.copysign(3, 0.), 3.0) self.assertEqual(math.copysign(4., -0.), -4.0) self.assertRaises(TypeError, math.copysign) # copysign should let us distinguish signs of zeros self.assertEqual(math.copysign(1., 0.), 1.) self.assertEqual(math.copysign(1., -0.), -1.) self.assertEqual(math.copysign(INF, 0.), INF) self.assertEqual(math.copysign(INF, -0.), NINF) self.assertEqual(math.copysign(NINF, 0.), INF) self.assertEqual(math.copysign(NINF, -0.), NINF) # and of infinities self.assertEqual(math.copysign(1., INF), 1.) self.assertEqual(math.copysign(1., NINF), -1.) self.assertEqual(math.copysign(INF, INF), INF) self.assertEqual(math.copysign(INF, NINF), NINF) self.assertEqual(math.copysign(NINF, INF), INF) self.assertEqual(math.copysign(NINF, NINF), NINF) self.assertTrue(math.isnan(math.copysign(NAN, 1.))) self.assertTrue(math.isnan(math.copysign(NAN, INF))) self.assertTrue(math.isnan(math.copysign(NAN, NINF))) self.assertTrue(math.isnan(math.copysign(NAN, NAN))) # copysign(INF, NAN) may be INF or it may be NINF, since # we don't know whether the sign bit of NAN is set on any # given platform. self.assertTrue(math.isinf(math.copysign(INF, NAN))) # similarly, copysign(2., NAN) could be 2. or -2. self.assertEqual(abs(math.copysign(2., NAN)), 2.)
def __init__(self, numer: int, denom: int) -> None: gcd = math.gcd(numer, denom) self.numer: int = int(math.copysign(numer, numer * denom)) // gcd self.denom: int = abs(denom) // gcd
def calc_trade_pnl( open_qtys: np.ndarray, open_prices: np.ndarray, new_qtys: np.ndarray, new_prices: np.ndarray, multiplier: float ) -> Tuple[np.ndarray, np.ndarray, float, float, float]: ''' >>> print(calc_trade_pnl( ... open_qtys = np.array([], dtype = float), open_prices = np.array([], dtype = float), ... new_qtys = np.array([-8, 9, -4]), new_prices = np.array([10, 11, 6]), multiplier = 100)) (array([-3.]), array([6.]), -3.0, 6.0, -1300.0) >>> print(calc_trade_pnl(open_qtys = np.array([], dtype = float), open_prices = np.array([], dtype = float), new_qtys = np.array([3, 10, -5]), ... new_prices = np.array([51, 50, 45]), multiplier = 100)) (array([8.]), array([50.]), 8.0, 50.0, -2800.0) >>> print(calc_trade_pnl(open_qtys = np.array([]), open_prices = np.array([]), ... new_qtys = np.array([-58, -5, -5, 6, -8, 5, 5, -5, 19, 7, 5, -5, 39]), ... new_prices = np.array([2080, 2075.25, 2070.75, 2076, 2066.75, 2069.25, 2074.75, 2069.75, 2087.25, 2097.25, 2106, 2088.25, 2085.25]), ... multiplier = 50)) (array([], dtype=float64), array([], dtype=float64), 0.0, 0, -33762.5) ''' # TODO: Cythonize this realized = 0. new_qtys = new_qtys.copy() new_prices = new_prices.copy() _open_prices = np.zeros(len(open_prices) + len(new_prices), dtype=float) _open_prices[:len(open_prices)] = open_prices _open_qtys = np.zeros(len(open_qtys) + len(new_qtys), dtype=float) _open_qtys[:len(open_qtys)] = open_qtys new_qty_indices = np.nonzero(new_qtys)[0] open_qty_indices = np.zeros(len(_open_qtys), dtype=int) nonzero_indices = np.nonzero(_open_qtys)[0] open_qty_indices[:len(nonzero_indices)] = nonzero_indices i = 0 # index into new_qty_indices to get idx of the new qty we are currently netting o = len(nonzero_indices) # virtual length of open_qty_indices j = 0 # index into open_qty_indices to get idx of the open qty we are currently netting k = len(open_qtys) # virtual length of _open_qtys # Try to net all new trades against existing non-netted trades. # Append any remaining non-netted new trades to end of existing trades while i < len(new_qty_indices): # Always try to net first non-zero new trade against first non-zero existing trade # FIFO acccounting new_idx = new_qty_indices[i] new_qty, new_price = new_qtys[new_idx], new_prices[new_idx] # print(f'i: {i} j: {j} k: {k} o: {o} oq: {_open_qtys} oqi: {open_qty_indices} op: {_open_prices} nq: {new_qtys} np: {new_prices}') if j < o: # while we still have open positions to net against open_idx = open_qty_indices[j] open_qty, open_price = _open_qtys[open_idx], _open_prices[open_idx] if math.copysign(1, open_qty) == math.copysign(1, new_qty): # Nothing to net against so add this trade to the array and wait for the next offsetting trade _open_qtys[k] = new_qty _open_prices[k] = new_price open_qty_indices[o] = k k += 1 o += 1 new_qtys[new_idx] = 0 i += 1 elif abs(new_qty) > abs(open_qty): # New trade has more qty than offsetting trade so: # a. net against offsetting trade # b. remove the offsetting trade # c. reduce qty of new trade open_qty, open_price = _open_qtys[open_idx], _open_prices[ open_idx] realized += open_qty * (new_price - open_price) # print(f'open_qty: {open_qty} open_price: {open_price} open_idx: {open_idx} i: {i} # j: {j} k: {k} l: {l} oq: {_open_qtys} oqi: {open_qty_indices} op: {_open_prices} nq: {new_qtys} np: {new_prices}') _open_qtys[open_idx] = 0 j += 1 new_qtys[new_idx] += open_qty else: # New trade has less qty than offsetting trade so: # a. net against offsetting trade # b. remove new trade # c. reduce qty of offsetting trade realized += new_qty * (open_price - new_price) new_qtys[new_idx] = 0 i += 1 _open_qtys[open_idx] += new_qty else: # Nothing to net against so add this trade to the open trades array and wait for the next offsetting trade _open_qtys[k] = new_qty _open_prices[k] = new_price open_qty_indices[o] = k k += 1 o += 1 new_qtys[new_idx] = 0 i += 1 mask = _open_qtys != 0 _open_qtys = _open_qtys[mask] _open_prices = _open_prices[mask] open_qty = np.sum(_open_qtys) if math.isclose(open_qty, 0): weighted_avg_price = 0 else: weighted_avg_price = np.sum(_open_qtys * _open_prices) / open_qty return _open_qtys, _open_prices, open_qty, weighted_avg_price, realized * multiplier
def testTanhSign(self): # check that tanh(-0.) == -0. on IEEE 754 systems self.assertEqual(math.tanh(-0.), -0.) self.assertEqual(math.copysign(1., math.tanh(-0.)), math.copysign(1., -0.))
#!/bin/python3 import math import random sign = lambda x: math.copysign(1, x) # I searched for an algorithm to get that bounding interval # without making random choice and enourmous array but I couldn't fund any # like I can't get results for any num over 1000 because of the enourmous # array and random choice, let's see how c++ would be different def bisection_root(c, error=0.1): function = lambda x: x**2 - c interval = [ i for i in range(-1 * c * 100, c * 100) ] # this is arbitrary interval from which we would choose a and b a = b = 0 # and I have the feeling that It won't work for some functions while True: # but It I guess it would work for finding roots and stuff # getting the interval while True: if sign(function(a)) != sign(function(b)): break a = random.choice(interval) b = random.choice(interval) m = (a + b) / 2 if sign(function(m)) == 1.0: # that means it is positive if function( m ) == 0: # that could happen if we got very very luck ... the algorithm gets it more than you think
def signed_sqare(x): # converts correlation into R-sqared, but of the same sign return copysign(x**2, x)
def test_can_generate_both_zeros_when_in_interval(l, r, sign): assert minimal(st.floats(l, r), lambda x: math.copysign(1, x) == sign) == sign * 0.0
def draw(self, ani_state): geometry = self.geometry # little shortcut fground = self.fground beatf = ani_state.state['beatf'] light_level = ani_state.state['light'] if fground: state_part = 'f_' else: state_part = 'b_' sp = ((ani_state.state[state_part + 'speed'] % 20) / 5.0) - 2.0 speedMillisDivider = math.copysign(10**(2.0 - abs(sp)), sp) animationSpeed = ani_state.millisDelta / speedMillisDivider if not fground: # the background should move slower to give a parallax effect animationSpeed /= 5.0 animationType = (int( ani_state.state[state_part + 'spin'] )) % 6 # spinZ, spinX, spinY, spinZSpinX, spinXSpinYSpinZ, noise if animationType == 0: geometry.rotateIncZ(animationSpeed) elif animationType == 1: geometry.rotateIncX(animationSpeed) elif animationType == 2: geometry.rotateIncY(animationSpeed) elif animationType == 3: geometry.rotateIncZ(animationSpeed) #if fground: geometry.rotateIncX(animationSpeed) elif animationType == 4: #if fground: geometry.rotateIncX(animationSpeed) geometry.rotateIncY(animationSpeed) geometry.rotateIncZ(animationSpeed) elif animationType == 5: #if fground: geometry.rotateIncX(animationSpeed * uniform(-1, 1)) geometry.rotateIncY(animationSpeed * uniform(-1, 1)) geometry.rotateIncZ(animationSpeed * uniform(-1, 1)) scale = ani_state.state[state_part + 'scale'] if fground: scale = 1.0 + (scale % 20) / 4.0 # from 0,10 to 1,5 else: scale = 15.0 + (scale % 20) / 4.0 geometry.scale(scale, scale, scale) shaderType = (int(ani_state.state[state_part + 'shader'])) % len( ShaderTypes.shadersTable) shader = ShaderTypes.shadersTable[shaderType] geometry.set_shader(shader) # use the palette scale to invert the colors paletteInvert = (int(ani_state.state[state_part + 'inv'])) % 2 if ani_state.state['f_paltt'] == 0: col1 = [i for i in ani_state.state['user1']] col2 = [i for i in ani_state.state['user2']] else: paletteEntry = PaletteTypes.paletteTable[(int( ani_state.state['f_paltt'])) % len(PaletteTypes.paletteTable)] col1 = [i for i in paletteEntry[0]] col2 = [i for i in paletteEntry[1]] ######## light levels ############### col1 = [i * light_level for i in col1] col2 = [i * light_level for i in col2] if paletteInvert: col1, col2 = col2, col1 # goes from 0 to 5, only the first four do something # swap, shades, random, flash # TODO music related function rather than frameCount % 8 swap = ani_state.state[state_part + 'fx1'] % 2 shde = ani_state.state[state_part + 'fx2'] % 2 rndm = ani_state.state[state_part + 'fx3'] % 2 flsh = ani_state.state[state_part + 'fx4'] % 2 fc = ani_state.frameCount % beatf if swap and fc == 0: col1, col2 = col2, col1 if shde and fc == 2: if uniform(0, 1) > 0.5: col1 = [0.5 + 0.5 * i for i in col1] col2 = [light_level - i for i in col2] else: col1 = [light_level - i for i in col1] col2 = [light_level - i for i in col2] if rndm and fc == 4: col1 = [uniform(0, light_level) for i in col1] col2 = [uniform(0, light_level) for i in col2] if flsh and fc == 6: col1 = [0.8 * light_level + 0.2 * i for i in col1] col2 = [0.8 * light_level + 0.2 * i for i in col2] geometry.set_custom_data(48, col1) geometry.set_custom_data(51, col2) shaderScale = 1.0 + int(ani_state.state[state_part + 'mult']) % 20.0 # with the dots shader, too few dots don't look super-cool, so adjust if shaderType == ShaderTypes.dots: shaderScale = 5.0 + shaderScale i = int(ani_state.state[state_part + 'param1']) param1 = ShaderTypes.petalTable[i % len(ShaderTypes.petalTable)] i = int(ani_state.state[state_part + 'param2']) param2 = ShaderTypes.powerTable[i % len(ShaderTypes.powerTable)] + ( ani_state.frameCount % 1000) / 250.0 - 2.0 geometry.set_custom_data( 54, [shaderScale, param1, param2]) # number of stripes etc geometry.draw(camera=self.cameraToUse)
def test_half_bounded_respects_sign_of_lower_bound(x): assert math.copysign(1, x) == 1
def test_does_not_generate_positive_if_right_boundary_is_negative(x): assert math.copysign(1, x) == -1
def method_infinity(self, space): if math.isinf(self.floatvalue): return space.newint(int(math.copysign(1, self.floatvalue))) return space.w_nil
def test_can_generate_both_zeros(sign): assert minimal( st.floats(), lambda x: math.copysign(1, x) == sign, ) == sign * 0.0
def Plot3DHits(self, track, color=1, style=0): ''' Plots the 3D hits from a track. ''' pix_coords = [] for hit in track.pixelHits(): if hit.isValid(): pix_coords.append(hit.x()) pix_coords.append(hit.y()) pix_coords.append(hit.z()) if pix_coords: pix_plot = ROOT.TPolyMarker3D( len(pix_coords) / 3, array('f', pix_coords), 2) pix_plot.SetMarkerColor(color) if style == 1: pix_plot.SetMarkerStyle(5) if style == 2: pix_plot.SetMarkerStyle(4) self.plots_3D.append(pix_plot) for hit in track.gluedHits(): if hit.isValid(): x = hit.x() y = hit.y() z = hit.z() if hit.isBarrel(): X = [x, x] Y = [y, y] Z = [z - sqrt(hit.zz()), z + sqrt(hit.zz())] else: X = [ x - copysign(sqrt(hit.xx()), x), x + copysign(sqrt(hit.xx()), x) ] Y = [ y - copysign(sqrt(hit.yy()), y), y + copysign(sqrt(hit.yy()), y) ] Z = [hit.z(), hit.z()] glu_plot = ROOT.TPolyLine3D(len(X), array("f", X), array("f", Y), array("f", Z)) #glu_plot.SetLineStyle(2) if style == 1: glu_plot.SetLineStyle(2) if style == 2: glu_plot.SetLineStyle(3) glu_plot.SetLineColor(color) self.plots_3D.append(glu_plot) for hit in track.stripHits(): if hit.isValid(): x = hit.x() y = hit.y() z = hit.z() if hit.isBarrel(): X = [x, x] Y = [y, y] Z = [z - 1.5 * sqrt(hit.zz()), z + 1.5 * sqrt(hit.zz())] else: X = [ x - 1.5 * copysign(sqrt(hit.xx()), x), x + 1.5 * copysign(sqrt(hit.xx()), x) ] Y = [ y - 1.5 * copysign(sqrt(hit.yy()), y), y + 1.5 * copysign(sqrt(hit.yy()), y) ] Z = [hit.z(), hit.z()] str_plot = ROOT.TPolyLine3D(len(X), array("f", X), array("f", Y), array("f", Z)) if style == 1: str_plot.SetLineStyle(2) if style == 2: str_plot.SetLineStyle(3) str_plot.SetLineColor(color) self.plots_3D.append(str_plot)
def sign(x): try: return math.copysign(1.0, x) except TypeError: raise TypeError('Expected float but got %r of type %s' % (x, type(x).__name__))
def float_round(value, precision_digits=None, precision_rounding=None, rounding_method='HALF-UP'): """Return ``value`` rounded to ``precision_digits`` decimal digits, minimizing IEEE-754 floating point representation errors, and applying the tie-breaking rule selected with ``rounding_method``, by default HALF-UP (away from zero). Precision must be given by ``precision_digits`` or ``precision_rounding``, not both! :param float value: the value to round :param int precision_digits: number of fractional digits to round to. :param float precision_rounding: decimal number representing the minimum non-zero value at the desired precision (for example, 0.01 for a 2-digit precision). :param rounding_method: the rounding method used: 'HALF-UP', 'UP' or 'DOWN', the first one rounding up to the closest number with the rule that number>=0.5 is rounded up to 1, the second always rounding up and the latest one always rounding down. :return: rounded float """ rounding_factor = _float_check_precision(precision_digits=precision_digits, precision_rounding=precision_rounding) if rounding_factor == 0 or value == 0: return 0.0 # NORMALIZE - ROUND - DENORMALIZE # In order to easily support rounding to arbitrary 'steps' (e.g. coin values), # we normalize the value before rounding it as an integer, and de-normalize # after rounding: e.g. float_round(1.3, precision_rounding=.5) == 1.5 # Due to IEE754 float/double representation limits, the approximation of the # real value may be slightly below the tie limit, resulting in an error of # 1 unit in the last place (ulp) after rounding. # For example 2.675 == 2.6749999999999998. # To correct this, we add a very small epsilon value, scaled to the # the order of magnitude of the value, to tip the tie-break in the right # direction. # Credit: discussion with OpenERP community members on bug 882036 normalized_value = value / rounding_factor # normalize sign = math.copysign(1.0, normalized_value) epsilon_magnitude = math.log(abs(normalized_value), 2) epsilon = 2**(epsilon_magnitude-52) # TIE-BREAKING: UP/DOWN (for ceiling[resp. flooring] operations) # When rounding the value up[resp. down], we instead subtract[resp. add] the epsilon value # as the the approximation of the real value may be slightly *above* the # tie limit, this would result in incorrectly rounding up[resp. down] to the next number # The math.ceil[resp. math.floor] operation is applied on the absolute value in order to # round "away from zero" and not "towards infinity", then the sign is # restored. if rounding_method == 'UP': normalized_value -= sign*epsilon rounded_value = math.ceil(abs(normalized_value)) * sign elif rounding_method == 'DOWN': normalized_value += sign*epsilon rounded_value = math.floor(abs(normalized_value)) * sign # TIE-BREAKING: HALF-UP (for normal rounding) # We want to apply HALF-UP tie-breaking rules, i.e. 0.5 rounds away from 0. else: normalized_value += math.copysign(epsilon, normalized_value) rounded_value = round(normalized_value) # round to integer result = rounded_value * rounding_factor # de-normalize return result
def border_point(self, t, s): s = math.copysign(1.0, s) Px, Py, Pz = self.progress_frame(t) w = self.a_width * (1 - t) + self.b_width * t return Px.deviate(Pz, w * s)
def reverse(self, xyz, y=None, z=None, M=False): '''Convert from geocentric C{(x, y, z)} to geodetic C{(lat, lon, height)}. @param xyz: Either an L{Ecef9Tuple}, an C{(x, y, z)} 3-tuple or C{scalar} ECEF C{x} coordinate in C{meter}. @keyword y: ECEF C{y} coordinate in C{meter} for C{scalar} B{C{xyz}} and B{C{z}}. @keyword z: ECEF C{z} coordinate in C{meter} for C{scalar} B{C{xyz}} and B{C{y}}. @keyword M: Optionally, return the rotation L{EcefMatrix} (C{bool}). @return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with geodetic coordinates C{(lat, lon, height)} for the given geocentric ones C{(x, y, z)}, case C{C}, optional L{EcefMatrix} C{M} and C{datum} if available. @raise EcefError: If B{C{xyz}} not L{Ecef9Tuple} or C{scalar} C{x} or B{C{y}} and/or B{C{z}} not C{scalar} for C{scalar} B{C{xyz}}. @note: In general, there are multiple solutions and the result which minimizes C{height} is returned, i.e., C{(lat, lon)} corresponds to the closest point on the ellipsoid. If there are still multiple solutions with different latitudes (applies only if C{z} = 0), then the solution with C{lat} > 0 is returned. If there are still multiple solutions with different longitudes (applies only if C{x} = C{y} = 0) then C{lon} = 0 is returned. The returned C{height} value is not below M{−E.a * (1 − E.e2) / sqrt(1 − E.e2 * sin(lat)**2)}. The returned C{lon} is in the range [−180°, 180°]. Like C{forward} above, M{v1 = Transpose(M) ⋅ v0}. ''' x, y, z, name = _xyzn4(xyz, y, z, Error=EcefError) sb, cb, d = _sch3(y, x) h = hypot(d, z) # distance to earth center if h > self._hmax: # We really far away (> 12 million light years). Treat the earth # as a point and h, above, is an acceptable approximation to the # height. This avoids overflow, e.g., in the computation of d # below. It's possible that h has overflowed to INF, that's OK. # Treat finite x, y, but r overflows to +INF by scaling by 2. sb, cb, r = _sch3(y / 2, x / 2) sa, ca, _ = _sch3(z / 2, r) C = 1 elif self.e4a: # Treat prolate spheroids by swapping R and Z here and by switching # the arguments to phi = atan2(...) at the end. p = (d / self.a)**2 q = self.e2m * (z / self.a)**2 if self.f < 0: p, q = q, p r = p + q - self.e4a e = self.e4a * q if e or r > 0: # Avoid possible division by zero when r = 0 by multiplying # equations for s and t by r^3 and r, resp. s = e * p / 4 # s = r^3 * s u = r = r / 6 r2 = r**2 r3 = r * r2 t3 = s + r3 disc = s * (r3 + t3) if disc < 0: # t is complex, but the way u is defined the result is real. # There are three possible cube roots. We choose the root # which avoids cancellation. Note, disc < 0 implies r < 0. u += 2 * r * cos(atan2(sqrt(-disc), -t3) / 3) else: # Pick the sign on the sqrt to maximize abs(T3). This # minimizes loss of precision due to cancellation. The # result is unchanged because of the way the T is used # in definition of u. if disc > 0: t3 += copysign(sqrt(disc), t3) # t3 = (r * t)^3 # N.B. cbrt always returns the real root, cbrt(-8) = -2. t = cbrt(t3) # t = r * t # t can be zero; but then r2 / t -> 0. if t: u += t + r2 / t v = sqrt(u**2 + e) # guaranteed positive # Avoid loss of accuracy when u < 0. Underflow doesn't occur in # E.e4 * q / (v - u) because u ~ e^4 when q is small and u < 0. uv = (e / (v - u)) if u < 0 else (u + v) # u+v, guaranteed positive # Need to guard against w going negative due to roundoff in uv - q. w = max(0.0, self.e2a * (uv - q) / (2 * v)) # Rearrange expression for k to avoid loss of accuracy due to # subtraction. Division by 0 not possible because uv > 0, w >= 0. k1 = k2 = uv / (sqrt(uv + w**2) + w) if self.f < 0: k1 -= self.e2 else: k2 += self.e2 sa, ca, h = _sch3(z / k1, d / k2) h *= k1 - self.e2m C = 2 else: # e = self.e4a * q == 0 and r <= 0 # This leads to k = 0 (oblate, equatorial plane) and k + E.e^2 = 0 # (prolate, rotation axis) and the generation of 0/0 in the general # formulas for phi and h, using the general formula and division # by 0 in formula for h. Handle this case by taking the limits: # f > 0: z -> 0, k -> E.e2 * sqrt(q) / sqrt(E.e4 - p) # f < 0: r -> 0, k + E.e2 -> -E.e2 * sqrt(q) / sqrt(E.e4 - p) q = self.e4a - p if self.f < 0: p, q, e = q, p, -1 else: e = -self.e2m sa, ca, h = _sch3(sqrt(q / self.e2m), sqrt(p)) h *= self.a * e / self.e2a if z < 0: sa = -sa # for tiny negative z, not for prolate C = 3 else: # self.e4a == 0 # Treat the spherical case. Dealing with underflow in the general # case with E.e2 = 0 is difficult. Origin maps to North pole, same # as with ellipsoid. sa, ca, _ = _sch3(z if h else 1, d) h -= self.a C = 4 r = Ecef9Tuple(x, y, z, degrees(atan2(sa, ca)), degrees(atan2(sb, cb)), h, C, self._Matrix(sa, ca, sb, cb) if M else None, self.datum) return self._xnamed(r, name)
def _addrow(self): """ Return cashflow table with one more line or raise an exception if there is no more line to add The same logic also applies to rem table 关于对于一个基金多个操作存在于同一交易日的说明:无法处理历史买入第一笔同时是分红日的情形, 事实上也不存在这种情形。无法处理一日多笔买卖的情形。 同一日既有卖也有买不现实,多笔买入只能在 csv 上合并记录,由此可能引起份额计算 0.01 的误差。可以处理分红日买入卖出的情形。 分级份额折算日封闭无法买入,所以程序直接忽略当天的买卖。因此不会出现多个操作共存的情形。 """ # the design on data remtable is disaster, it is very dangerous though works now # possibly failing cases include: # 买卖日记录是节假日,而顺延的日期恰好是折算日(理论上无法申赎)或分红日(可能由于 date 和 rdate 的错位而没有考虑到), # 又比如周日申购记录,周一申购记录,那么周日记录会现金流记在周一,继续现金流标更新将从周二开始,周一数据被丢弃 code = self.aim.code if len(self.cftable) == 0: if len(self.status[self.status[code] != 0]) == 0: raise Exception("no other info to be add into cashflow table") i = 0 while self.status.iloc[i].loc[code] == 0: i += 1 value = self.status.iloc[i].loc[code] date = self.status.iloc[i].date self.lastdate = date if len(self.price[self.price["date"] >= date]) > 0: date = self.price[self.price["date"] >= date].iloc[0]["date"] else: date = self.price[self.price["date"] <= date].iloc[-1]["date"] # 这里没有像下边部分一样仔细处理单独的 lastdate,hopefully 不会出现其他奇怪的问题,有 case 再说 # https://github.com/refraction-ray/xalpha/issues/47 # 凭直觉这个地方的处理很可能还有其他 issue if value > 0: feelabel = 100 * value - int(100 * value) if round(feelabel, 1) == 0.5: # binary encoding, 10000.005 is actually 10000.0050...1, see issue #59 feelabel = feelabel - 0.5 if abs(feelabel) < 1e-4: feelabel = 0 else: feelabel *= 100 else: feelabel = None value = int(value * 100) / 100 assert feelabel is None or feelabel >= 0.0, "自定义申购费必须为正值" rdate, cash, share = self.aim.shengou(value, date, fee=feelabel) rem = rm.buy([], share, rdate) else: raise TradeBehaviorError( "You cannot sell first when you never buy") elif len(self.cftable) > 0: # recorddate = list(self.status.date) if not getattr(self, "lastdate", None): lastdate = self.cftable.iloc[-1].date + pd.Timedelta(1, unit="d") else: lastdate = self.lastdate + pd.Timedelta(1, unit="d") while (lastdate not in self.aim.specialdate) and ( (lastdate not in self.recorddate_set) or ((lastdate in self.recorddate_set) and (self.status[self.status["date"] == lastdate].loc[:, code].any() == 0))): lastdate += pd.Timedelta(1, unit="d") if (lastdate - yesterdayobj()).days >= 1: raise Exception( "no other info to be add into cashflow table") if (lastdate - yesterdayobj()).days >= 1: raise Exception("no other info to be add into cashflow table") date = lastdate # 无净值日优先后移,无法后移则前移 # 还是建议日期记录准确,不然可能有无法完美兼容的错误出现 if len(self.price[self.price["date"] >= date]) > 0: date = self.price[self.price["date"] >= date].iloc[0]["date"] else: date = self.price[self.price["date"] <= date].iloc[-1]["date"] if date != lastdate and date in list(self.status.date): # 日期平移到了其他记录日,很可能出现问题! logger.warning( "账单日期 %s 非 %s 的净值记录日期,日期智能平移后 %s 与账单其他日期重合!交易处理极可能出现问题!! " "靠后日期的记录被覆盖" % (lastdate, self.code, date)) self.lastdate = lastdate if date > lastdate: self.lastdate = date # see https://github.com/refraction-ray/xalpha/issues/27, begin new date from last one in df is not reliable label = self.aim.dividend_label # 现金分红 0, 红利再投 1 cash = 0 share = 0 rem = self.remtable.iloc[-1].rem rdate = date if (lastdate in self.recorddate_set) and (date not in self.aim.zhesuandate): # deal with buy and sell and label the fenhongzaitouru, namely one label a 0.05 in the original table to label fenhongzaitouru value = self.status[ self.status["date"] <= lastdate].iloc[-1].loc[code] if date in self.aim.fenhongdate: # 0.05 的分红行为标记,只有分红日才有效 fenhongmark = round(10 * value - int(10 * value), 1) if fenhongmark == 0.5 and label == 0: label = 1 # fenhong reinvest value = value - math.copysign(0.05, value) elif fenhongmark == 0.5 and label == 1: label = 0 value = value - math.copysign(0.05, value) if value > 0: # value stands for purchase money feelabel = 100 * value - int(100 * value) if int(10 * feelabel) == 5: feelabel = (feelabel - 0.5) * 100 else: feelabel = None value = int(value * 100) / 100 rdate, dcash, dshare = self.aim.shengou( value, date, fee=feelabel ) # shengou fee is in the unit of percent, different than shuhui case rem = rm.buy(rem, dshare, rdate) elif value < -0.005: # value stands for redemp share feelabel = int(100 * value) - 100 * value if int(10 * feelabel) == 5: feelabel = feelabel - 0.5 else: feelabel = None value = int(value * 100) / 100 rdate, dcash, dshare = self.aim.shuhui( -value, date, self.remtable.iloc[-1].rem, fee=feelabel) _, rem = rm.sell(rem, -dshare, rdate) elif value >= -0.005 and value < 0: # value now stands for the ratio to be sold in terms of remain positions, -0.005 stand for sell 100% remainshare = sum(self.cftable[ self.cftable["date"] <= date].loc[:, "share"]) ratio = -value / 0.005 rdate, dcash, dshare = self.aim.shuhui( remainshare * ratio, date, self.remtable.iloc[-1].rem, 0) _, rem = rm.sell(rem, -dshare, rdate) else: # in case value=0, when specialday is in record day rdate, dcash, dshare = date, 0, 0 cash += dcash share += dshare if date in self.aim.specialdate: # deal with fenhong and xiazhe comment = self.price[self.price["date"] == date].iloc[0].loc["comment"] if isinstance(comment, float): if comment < 0: dcash2, dshare2 = ( 0, sum([ myround(sh * (-comment - 1)) for _, sh in rem ]), ) # xiazhe are seperately carried out based on different purchase date rem = rm.trans(rem, -comment, date) # myround(sum(cftable.loc[:,'share'])*(-comment-1)) elif comment > 0 and label == 0: dcash2, dshare2 = ( myround( sum(self.cftable.loc[:, "share"]) * comment), 0, ) rem = rm.copy(rem) elif comment > 0 and label == 1: dcash2, dshare2 = ( 0, myround( sum(self.cftable.loc[:, "share"]) * (comment / self.price[self.price["date"] == date].iloc[0].netvalue)), ) rem = rm.buy(rem, dshare2, date) cash += dcash2 share += dshare2 else: raise ParserFailure("comments not recognized") self.cftable = self.cftable.append( pd.DataFrame([[rdate, cash, share]], columns=["date", "cash", "share"]), ignore_index=True, ) self.remtable = self.remtable.append(pd.DataFrame( [[rdate, rem]], columns=["date", "rem"]), ignore_index=True)
def main(): # create GraphWin win = GraphWin('Linear Regression', 600, 600) # Set window coordinates for text entry win.setCoords(0, 0, 10, 10) # introduce program msg = Text(Point(5, 7), 'After user creates points, a linear regression is drawn.') msg.draw(win) win.getMouse() msg.undraw() # Set window coordinates for graphing (-11, -11, 11, 12) win.setCoords(-11, -11, 11, 12) # call drawAxes() to draw axes drawAxes(win, -10, -10, 10, 10, "Linear Regression") # draw Done box in lower left corner buttonLL = Point(-10.5, -10.5) buttonUR = Point(-8.5, -9.5) button = Rectangle(buttonLL, buttonUR) button.draw(win) buttonText = Text(Point(-9.5, -10), 'Done') buttonText.draw(win) # display instructions msg = Text( Point(5, 7), "Create points by clicking on the graph.\nClick 'Done' when finished.\n\nClick anywhere to start." ) msg.draw(win) win.getMouse() msg.undraw() # initialize Regression object bestFit = Regresion() # while True while True: # get mouse click graphPt = win.getMouse() # if Done, exit loop # Done is true when mouse click is within borders of Done rectangle (button) graphPtX = graphPt.getX() graphPtY = graphPt.getY() if graphPtX >= buttonLL.getX() and graphPtX <= buttonUR.getX() and \ graphPtY >= buttonLL.getY() and graphPtY <= buttonUR.getY(): break # otherwise, draw point and add point to bestFit bestFit.addPoint(graphPt) Point(graphPtX, graphPtY).draw(win) # calculate y coordinates for min and max x coordinates (y = meanY + slope(x - meanX)) y1 = bestFit.predict(-10) y2 = bestFit.predict(10) # draw line between those two coordinate pairs Line(Point(-10, y1), Point(10, y2)).draw(win) # calculate y-intercept yInt = bestFit.predict(0) # display equation of line in y = mx + b format Text(Point(5, copysign(min(abs(y2), 10), y2)), 'y = {:.2f}x + {:.2f}'.format(bestFit.slope(), yInt)).draw(win) # wait for mouse click win.getMouse()
def reverse(self, xyz, y=None, z=None, **no_M): # PYCHOK unused M '''Convert from geocentric C{(x, y, z)} to geodetic C{(lat, lon, height)} transcribed from I{Chris Veness}' U{JavaScript <https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html>}. Uses B. R. Bowring’s formulation for μm precision in concise form: U{'The accuracy of geodetic latitude and height equations' <https://www.ResearchGate.net/publication/ 233668213_The_Accuracy_of_Geodetic_Latitude_and_Height_Equations>}, Survey Review, Vol 28, 218, Oct 1985. @param xyz: Either an L{Ecef9Tuple}, an C{(x, y, z)} 3-tuple or C{scalar} ECEF C{x} coordinate in C{meter}. @keyword y: ECEF C{y} coordinate in C{meter} for C{scalar} B{C{xyz}} and B{C{z}}. @keyword z: ECEF C{z} coordinate in C{meter} for C{scalar} B{C{xyz}} and B{C{y}}. @keyword no_M: Rotation matrix C{M} not available. @return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with geodetic coordinates C{(lat, lon, height)} for the given geocentric ones C{(x, y, z)}, case C{C}, L{EcefMatrix} C{M} always C{None} and C{datum} if available. @raise EcefError: If B{C{xyz}} not L{Ecef9Tuple} or C{scalar} C{x} or B{C{y}} and/or B{C{z}} not C{scalar} for C{scalar} B{C{xyz}}. @see: Ralph M. Toms U{'An Efficient Algorithm for Geocentric to Geodetic Coordinate Conversion'<https://www.OSTI.gov/scitech/biblio/110235>}, Sept 1995 and U{'An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion'<https://www.OSTI.gov/scitech/servlets/purl/231228>}, Apr 1996, both from Lawrence Livermore National Laboratory (LLNL). ''' x, y, z, name = _xyzn4(xyz, y, z, Error=EcefError) E = self.ellipsoid p = hypot(x, y) # distance from minor axis r = hypot(p, z) # polar radius if min(p, r) > EPS: # parametric latitude (Bowring eqn 17, replaced) t = (E.b * z) / (E.a * p) * (1 + E.e22 * E.b / r) c = 1 / hypot1(t) s = t * c # geodetic latitude (Bowring eqn 18) a = atan2(z + E.e22 * E.b * s**3, p - E.e2 * E.a * c**3) b = atan2(y, x) # ... and longitude # height above ellipsoid (Bowring eqn 7) sa, ca = sincos2(a) # r = E.a / E.e2s(sa) # length of normal terminated by minor axis # h = p * ca + z * sa - (E.a * E.a / r) h = fsum_(p * ca, z * sa, -E.a * E.e2s(sa)) C, lat, lon = 1, degrees90(a), degrees180(b) # see <https://GIS.StackExchange.com/questions/28446> elif p > EPS: # lat arbitrarily zero C, lat, lon, h = 2, 0.0, degrees180(atan2(y, x)), p - E.a else: # polar lat, lon arbitrarily zero C, lat, lon, h = 3, copysign(90.0, z), 0.0, abs(z) - E.b r = Ecef9Tuple(x, y, z, lat, lon, h, C, None, self.datum) return self._xnamed(r, name)
def legacy_round(number, points=0): p = 10**points return float(math.floor((number * p) + math.copysign(0.5, number))) / p
# return log_1arg_der(*args) # Argument number check #except TypeError: # return 1/args[0]/math.log(args[1]) # 2-argument form fixed_derivatives = { # In alphabetical order, here: 'acos': [lambda x: -1/math.sqrt(1-x**2)], 'acosh': [lambda x: 1/math.sqrt(x**2-1)], 'asin': [lambda x: 1/math.sqrt(1-x**2)], 'asinh': [lambda x: 1/math.sqrt(1+x**2)], 'atan': [lambda x: 1/(1+x**2)], 'atan2': [lambda y, x: x/(x**2+y**2), # Correct for x == 0 lambda y, x: -y/(x**2+y**2)], # Correct for x == 0 'atanh': [lambda x: 1/(1-x**2)], 'ceil': [lambda x: 0], 'copysign': [lambda x, y: (1 if x >= 0 else -1) * math.copysign(1, y), lambda x, y: 0], 'cos': [lambda x: -math.sin(x)], 'cosh': [math.sinh], 'degrees': [lambda x: math.degrees(1)], 'exp': [math.exp], 'fabs': [lambda x: 1 if x >= 0 else -1], 'floor': [lambda x: 0], 'hypot': [lambda x, y: x/math.hypot(x, y), lambda x, y: y/math.hypot(x, y)], 'log': [log_der0, lambda x, y: -math.log(x, y)/y/math.log(y)], 'log10': [lambda x: 1/x/math.log(10)], 'log1p': [lambda x: 1/(1+x)], 'pow': [lambda x, y: y*math.pow(x, y-1), lambda x, y: math.log(x) * math.pow(x, y)],