Re: bigatom in The Archive

new topic     » goto parent     » topic index » view thread      » older message » newer message

Also I have trigonometric functions (sin, cos, arctan), but I can not work well with my bigatoms. If someone who knows more than I want to review and perhaps find and fix.

This is what I have:

 
 
-- ##################################### 
-- ###   FUNCIONES TRIGONOMÉTRICAS   ### 
-- ##################################### 
-- 
 
-- sin(x) = x - x^3/3! + x^5/5! - x^7/7! ...  
override function sin(atom x) 
   integer n = 3 
   atom curr = x, res = x 
   atom nfact = 6, x2 = -x * x 
   atom xpow = x2 * x 
    
   while curr do 
      curr   = xpow / nfact 
      res   += curr 
      n     += 2 
      nfact *= n * n - n 
      xpow  *= x2 
   end while 
 
   return res 
end function 
 
 
export function ba_sin(object x) 
 
   if not bigatom(x) then 
      if atom(x) then 
         return ba_new(sin(x)) 
      end if 
      x = ba_new(x) 
   end if 
 
   integer n = 1 
   sequence curr, prev, res 
   sequence nfact, mx2 
   sequence mx, xpow 
 
   sequence sc = scale(SCALE + 2, 0) 
    
   nfact = {1, 0, {6}} 
   mx   = x 
   mx[SIGN] = -mx[SIGN] 
   res  = ZERO 
   prev = ZERO 
   curr = x 
   mx2   = ba_multiply(mx, x) 
   xpow =  x   -- ba_multiply(x, mx2) 
   while not eu:equal(prev, curr) do 
--   while curr[SIGN] do 
      prev  = curr 
      res   = ba_add(res, curr) 
      n    += 2 
      nfact = ba_sub(ba_multiply(n, n), n) 
      xpow  = ba_multiply(xpow, mx2) 
      curr  = ba_divide(xpow, nfact) 
   end while 
   scale(sc) 
   res[DIGITS] = remove(res[DIGITS], 
                          res[EXPONENT] + 2 + SCALE, 
                          length(res[DIGITS])) 
 
   return normalize(res) 
end function 
 
 
-- cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - ...  
override function cos(atom x) 
   integer n = 2 
   atom curr = 1, res = x 
   atom nfact = 2, x2 = -x * x 
   atom xpow = x2 
    
   while curr do 
      curr = xpow / nfact 
      res   += curr 
      n     += 2 
      nfact *= n * n - n 
      xpow  *= x2 
   end while 
 
   return res 
end function 
 
 
-- sacada de bc 
-- Usa la fórmula: 
--   atan(x) = atan(c) + atan((x-c)/(1+xc)) para c pequeño (0.2 en este caso) 
-- Por debajo de 0.2, usa la serie: 
--   atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...  
--  
override function arctan(atom x) 
   integer sg = 1, mult = 0, n = 3 
   atom  curr, res, xpow, x2   
   atom ap2 = 0.0 
 
   if x < 0 then 
     sg = -1 
     x  = -x 
   end if 
    
   if x > 0.2 then 
      ap2 = arctan(0.2)  
   end if 
    
   -- hacer x <= 0.2 
   while x > 0.2 do 
      mult += 1 
      x = (x - 0.2) / (1 + x * 0.2) 
   end while 
    
   curr  = x 
   xpow = x 
   res  = x 
   x2   = -x * x 
   while curr do 
      xpow *= x2 
      curr  = xpow / n 
      res  += curr 
      n    += 2 
   end while 
 
   return sg * (res + mult * ap2) 
end function 
 
 
export function ba_arctan(object x) 
 
   if not bigatom(x) then 
      if atom(x) then 
         return ba_new(arctan(x)) 
      end if 
      x = ba_new(x) 
   end if 
    
   sequence sc = scale(SCALE + (SCALE + 1)/ 2, 0) 
    
   integer sg = 1, mult = 0, n = 3 
   sequence  curr, res, xpow, x2   
   sequence ap2 = ZERO, p2 = {1,-1,{2}} 
 
   if x[SIGN] < 0 then 
     sg = -1 
     x[SIGN] = -x[SIGN] 
   end if 
    
   if eu:compare(x, p2) = SG_PLUS then 
      ap2 = ba_arctan(0.2)  
   end if 
 
   -- hacer x <= 0.2 
   sequence a, b 
   while eu:compare(x, p2) = SG_PLUS do 
      mult += 1 
    --  x = (x - 0.2) / (1 + x * 0.2) 
      a = ba_sub(x, p2) 
      b = ba_add(ONE, ba_multiply(x, p2)) 
      x = ba_divide(a, b) 
   end while 
    
   sequence limit = {x[SIGN], -(SCALE + 1), {1}}   -- ba_power({x[SIGN],1,{1}}, -(SCALE + 6))  
--   sequence prev = ZERO 
   curr  = x 
   xpow = x 
   res  = x 
   x2   = ba_multiply(x, x) 
   x2[SIGN] = -x2[SIGN] 
--   while eu:compare(curr, prev) do      -- esto es interminable 
--   while curr[SIGN] do                  -- como esto, es lo mismo 
   while eu:compare(curr, limit) > 0 do   -- esto no es correcto, sale antes de tiempo 
--      prev = curr 
      xpow = ba_multiply(x, x2) 
      curr = ba_divide(xpow, n) 
      res  = ba_add(res, curr) 
      n   += 2 
      limit[SIGN] = -limit[SIGN] 
   end while 
   scale(sc) 
   res = ba_add(res, ba_multiply(mult, ap2)) 
 
   return ba_multiply(res, sg) 
end function 
-- 

Atoms seem to go well with, but not bigatom. I do not know more, maybe later when I learn more ... but it would be very good to include sin, cos and arctan to complete the library. (arctan is a very important function)

Greets.

cargoan

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu