###########################################################1# pylang Standard Library2# Author: Alexander Tsepkov3# Copyright 2013 Pyjeon Software LLC4# License: Apache License 2.05# This library is covered under Apache license, so that6# you can distribute it with your pylang applications.7###########################################################89# basic implementation of Python's 'math' library1011# NOTE: this is only meant to aid those porting lots of Python code into pylang.12# If you're writing a new pylang application, in most cases you probably want to13# use JavaScript's Math module directly instead1415pi = Math.PI16e = Math.E171819########################################20# Number-theoretic and representation functions21########################################22def ceil(x):23return Math.ceil(x)242526def copysign(x, y):27x = Math.abs(x)28if y < 0:29return -x30else:31return x323334def fabs(x):35return Math.abs(x)363738def factorial(x):39if Math.abs(int(x)) is not x:40raise ValueError("factorial() only accepts integral values")41factorial.cache = []4243if x <= 12:44# normal javascript integer45def r(n):46if n is 0 or n is 1:47return 148if not factorial.cache[n]:49factorial.cache[n] = r(n - 1) * n50return factorial.cache[n]51else:52# use BigInt to avoid overflow53def r(n):54if n is 0 or n is 1:55return BigInt(1)56if not factorial.cache[n]:57factorial.cache[n] = r(n - 1) * BigInt(n)58return factorial.cache[n]5960return r(x)616263def floor(x):64return Math.floor(x)656667def fmod(x, y):68# javascript's % operator isn't consistent with C fmod implementation, this function is69while y <= x:70x -= y71return x727374def fsum(iterable):75# like Python's fsum, this method is much more resilient to rounding errors than regular sum76partials = [] # sorted, non-overlapping partial sums77for x in iterable:78i = 079for y in partials:80if Math.abs(x) < Math.abs(y):81x, y = y, x82hi = x + y83lo = y - (hi - x)84if lo:85partials[i] = lo86i += 187x = hi88#partials[i:] = [x]89partials.splice(i, partials.length - i, x)90return sum(partials)919293def isinf(x):94return not isFinite(x)959697def isnan(x):98return isNaN(x)99100101def modf(x):102m = fmod(x, 1)103return m, x - m104105106def trunc(x):107return x | 0108109110########################################111# Power and logarithmic functions112########################################113def exp(x):114return Math.exp(x)115116117def expm1(x):118# NOTE: Math.expm1() is currently only implemented in Firefox, this provides alternative implementation119# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1120#return Math.expm1(x)121if Math.abs(x) < 1e-5:122return x + 0.5 * x * x123else:124return Math.exp(x) - 1125126127def log(x, base=e):128return Math.log(x) / Math.log(base)129130131def log1p(x):132# NOTE: Math.log1p() is currently only implemented in Firefox, this provides alternative implementation133# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p134# this version has been taken from http://phpjs.org/functions/log1p/135# admittedly it's not as accurate as MDN version, as you can see from math.log1p(1) result136ret = 0137n = 50138if x <= -1:139return Number.NEGATIVE_INFINITY140if x < 0 or x > 1:141return Math.log(1 + x)142for i in range(1, n):143if i % 2 is 0:144ret -= Math.pow(x, i) / i145else:146ret += Math.pow(x, i) / i147return ret148149150def log10(x):151# NOTE: Math.log10() is currently only implemented in Firefox, this provides alternative implementation152# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10153# I didn't find a more accurate algorithm so I'm using the basic implementation154return Math.log(x) / Math.LN10155156157def pow(x, y):158if x < 0 and int(y) is not y:159raise ValueError('math domain error')160if isnan(y) and x is 1:161return 1162return Math.pow(x, y)163164165def sqrt(x):166return Math.sqrt(x)167168169########################################170# Trigonometric functions171########################################172def acos(x):173return Math.acos(x)174175176def asin(x):177return Math.asin(x)178179180def atan(x):181return Math.atan(x)182183184def atan2(y, x):185return Math.atan2(y, x)186187188def cos(x):189return Math.cos(x)190191192def sin(x):193return Math.sin(x)194195196def hypot(x, y):197return Math.sqrt(x * x + y * y)198199200def tan(x):201return Math.tan(x)202203204########################################205# Angular conversion206########################################207def degrees(x):208return x * 180 / pi209210211def radians(x):212return x * pi / 180213214215########################################216# Hyperbolic functions217########################################218def acosh(x):219# NOTE: will be replaced with official, when it becomes mainstream220# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh221return Math.log(x + Math.sqrt(x * x - 1))222223224def asinh(x):225# NOTE: will be replaced with official, when it becomes mainstream226# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh227return Math.log(x + Math.sqrt(x * x + 1))228229230def atanh(x):231# NOTE: will be replaced with official, when it becomes mainstream232# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh233return 0.5 * Math.log((1 + x) / (1 - x))234235236def cosh(x):237# NOTE: will be replaced with official, when it becomes mainstream238# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh239return (Math.exp(x) + Math.exp(-x)) / 2240241242def sinh(x):243# NOTE: will be replaced with official, when it becomes mainstream244# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh245return (Math.exp(x) - Math.exp(-x)) / 2246247248def tanh(x):249# NOTE: will be replaced with official, when it becomes mainstream250# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh251return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x))252253254#import stdlib255#print(math.ceil(4.2))256#print(math.floor(4.2))257#print(math.fabs(-6))258#print(math.copysign(-5, 7))259#print(math.factorial(4))260#print(math.fmod(-1e100, 1e100))261#262#d = [0.9999999, 1, 2, 3]263#print(sum(d), math.fsum(d))264#print(math.isinf(5), math.isinf(Infinity))265#print(math.modf(5.5))266#print(math.trunc(2.6), math.trunc(-2.6))267#print(math.exp(1e-5), math.expm1(1e-5))268#print(math.log(10), math.log(10, 1000))269#print(math.log1p(1e-15), math.log1p(1))270#print(math.log10(1000), math.log(1000, 10))271#print(math.pow(1, 0), math.pow(1, NaN), math.pow(0, 0), math.pow(NaN, 0), math.pow(4,3), math.pow(100, -2))272#print(math.hypot(3,4))273#print(math.acosh(2), math.asinh(1), math.atanh(0.5), math.cosh(1), math.cosh(-1), math.sinh(1), math.tanh(1))274275276