Tuesday, November 10, 2009

Calculation of PI

http://www.reddit.com/r/programming/comments/9uxjo/dear_progg... on Twitpic

Today I was drawing answers to a quiz using boxes that stood for binary representations of the answers and realized that any regular polygon is composed of triangles. I thought back to a question I saw on reddit where someone had challeneged the readers to determine the radius of a circle without knowing what PI was.
I figured this could be a way to find the perimeter of any polygon using its "radius". Knowing that PI is the ratio of the circumference to the diameter , a polygon with the number of sides approaching infinity will have a ratio of perimeter to diameter approximately equal to PI.


I started with a square. Its composed of 4 triangles and I used the law of sines to find the perimeter. The angle of the center is 360/4 (where 4 is n for squares being 4 sided) then other 2 angles are (180-(360/4))/2 or half the remaining degrees left in the triangle. If the radius is 1 then the perimeter of the square in terms of the law of sines is (sin(90)*4)/sin(135). If we continue this for a hexagon we find that the perimeter of a hexagon with radius 1 is 6. (sin(60)*6)/sin(60)).



We can take the limit of this function as the number of sides approaches infinity with the radius of 1. We take the result and divide it by the diameter of the "circle" which would be 2.



Here is the resulting code.


dr=lambda{|x| x*(Math::PI/180)} #degrees to radians (cuz Math.sin won't take degrees)
p=lambda{|r,n| (r*Math.sin(dr[360.0/n])*n)/Math.sin(dr[(180-(360.0/n))/2.0])}
pitime=lambda{|r|
last=0
4.upto(1.0/0) {|x| #from the perimeter of a square to infinity
y=p[r,x]/(r*2) #calculate ratio of perimeter to diameter
break if y==last
last=y
}
last
}
puts pitime[1.0]
>> 3.14159265341633

(Took 172599 iterations in 1.5seconds to get that number)

Friday, April 17, 2009

How to implement interactive breakpoint - like functionality.

When calling a script from irb/command line. You can use this snippet to take statements from stdin and evaluate them in the current context just like IRB. Use qq to stop.



if options[:debug]
STDOUT << ">> "
while (cmd=gets.chomp)!="qq"
puts eval(cmd).inspect
STDOUT << ">> "
end
end

Thursday, March 05, 2009

Limits and Derivatives and Ruby

I read this article about Lisp: http://funcall.blogspot.com/2009/03/not-lisp-again.html
I wanted to try doing the same in Ruby.
I didn't like his setting DX as a constant close to 0 to shortcut not creating a function to figure the limit.




lim=lambda{|f,h|
y=h
1.upto(1.0/0) {|p| ##to infinity
x=h+(1.0/10)**p ##increase how close x is to h 1.0,0.1,0.001 etc..
fx=f[x] ##get f(x)
break if y==fx ##if we start getting the same val, stop
y=fx ##store the last val
}
y ##return where we stopped
}
ddx=lambda {|f|
lambda {|x|
lim[lambda{|dx| ##the limit of the derivative function
(f[x+dx]-f[x])/dx
},0] #as h approaches 0
}
}


Here are some results
(Infinite limits) http://www.cliffsnotes.com/WileyCDA/CliffsReviewTopic/Infinite-Limits.topicArticleId-39909,articleId-39873.html

irb(main):319:0> g=lambda{|x| 1/(x**2)}
=> #
irb(main):320:0> lim[g,0]
=> Infinity
irb(main):321:0> g=lambda{|x| (1/(x**2))-(1/(x**3))}
=> #
irb(main):322:0> lim[g,0]
=> -Infinity

Derivatives

irb(main):326:0> g=lambda{|x| x**3}
=> #
irb(main):327:0> ddx[g][2]
=> 12.0000009928844


I tried for hours to get the limit to resolve to a nice integer... but could never quite get it to be more precise. I did this because i googled "derivatives calculus ruby" and couldn't find anything about this. Why not?