Skip to content

Instantly share code, notes, and snippets.

@ox
Created February 8, 2011 05:04
Show Gist options
  • Save ox/815892 to your computer and use it in GitHub Desktop.
Save ox/815892 to your computer and use it in GitHub Desktop.
This is a little something I cooked up over a day or two. It solves physics problems easily when solving for a single variable. It's not Wolfram|Alpha or Maple, but it's nifty in a bind. Hope it's useful!
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
}
}
class Object; alias :is :==; end
class Formula
attr_accessor :formula, :variables
def initialize(formula)
@formula = formula
@variables = Hash.new
self.process(formula)
end
def process(formula); formula.scan(/([a-zA-Z])/).each { |v| @variables[v[0]] = v[0] };end
def to_s; @formula; end
def diff(var="x"); end
def solve(args,show_args=false)
@temp_vars = Hash.new
@temp_vars.replace @variables #not messing with the stored vars
args.each_key do |i|
@temp_vars[i] = args[i] unless args[i].is nil
end
if show_args;puts "using #{@temp_vars.inspect}";end
nf = formula
@temp_vars.each_key do |k|
nf = nf.gsub(/#{k}/, "#{@temp_vars[k]}")
end
if(nf.match(/[a-zA-Z]/)) #if there are still variables
return nf
else
instance_eval(nf)
end
end
def solve!(args,show_args=false)
args.each_key do |i|
@variables[i] = args[i] unless args[i].is nil
end
if show_args;puts "using #{@variables.inspect}";end
nf = formula
@variables.each_key do |k|
nf = nf.gsub(/#{k}/, "#{@variables[k]}")
end
if(nf.match(/[a-zA-Z]/)) #if there are still variables
return nf
else
instance_eval(nf)
end
end
alias :[] :solve
def *(arg);return Formula.new("(#{@formula})*#{arg}");end
def /(arg);return Formula.new("(#{@formula})/#{arg}");end
def +(arg);return Formula.new("#{@formula}+#{arg}");end
def -(arg);return Formula.new("#{@formula}-#{arg}");end
def op(s, arg, parens=true)
@formula = parens ? "(#{@formula})#{s}#{arg}" : "#{@formula}#{s}#{arg}"
return self
end
def solve_for(var)
#is var inside parens?
lside = Formula.new
end
end
# example usage
# g=lambda{|x| Math.exp(x)}
# puts ddx[g][2]
# k = Formula.new("x+(v*t)-((0.5*9.8)*(t**2))")
#
# (0..6).step(0.25).each do |t|
# solution = k.solve({"x"=> 0, "v"=> 12, "t"=> t})
# puts "#{t.to_s.rjust(4)} #{solution}"
# end
# k = Formula.new("x+(v*t)-((0.5*9.8)*(t**2))")
# puts k.variables.inspect
# puts k[{"x"=> 0, "v"=> 12, "t" => 3},true]
# puts (k+4)[{"x"=> 0, "v"=> 12, "t" => 5},true]
#
# puts k+2
# puts k*4
# puts k.op("**",2)[{"x"=> 0, "v"=> 12},true]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment