keisan 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -1
  3. data/keisan.gemspec +1 -0
  4. data/lib/keisan.rb +30 -0
  5. data/lib/keisan/ast/assignment.rb +44 -17
  6. data/lib/keisan/ast/block.rb +60 -0
  7. data/lib/keisan/ast/boolean.rb +5 -5
  8. data/lib/keisan/ast/builder.rb +10 -207
  9. data/lib/keisan/ast/cell.rb +60 -0
  10. data/lib/keisan/ast/constant_literal.rb +9 -0
  11. data/lib/keisan/ast/exponent.rb +6 -6
  12. data/lib/keisan/ast/function.rb +12 -8
  13. data/lib/keisan/ast/indexing.rb +25 -15
  14. data/lib/keisan/ast/line_builder.rb +230 -0
  15. data/lib/keisan/ast/list.rb +28 -1
  16. data/lib/keisan/ast/literal.rb +0 -8
  17. data/lib/keisan/ast/logical_and.rb +1 -1
  18. data/lib/keisan/ast/logical_or.rb +1 -1
  19. data/lib/keisan/ast/multi_line.rb +28 -0
  20. data/lib/keisan/ast/node.rb +32 -24
  21. data/lib/keisan/ast/number.rb +31 -31
  22. data/lib/keisan/ast/operator.rb +12 -4
  23. data/lib/keisan/ast/parent.rb +4 -4
  24. data/lib/keisan/ast/plus.rb +10 -10
  25. data/lib/keisan/ast/string.rb +3 -3
  26. data/lib/keisan/ast/times.rb +8 -8
  27. data/lib/keisan/ast/unary_identity.rb +1 -1
  28. data/lib/keisan/ast/unary_inverse.rb +7 -7
  29. data/lib/keisan/ast/unary_minus.rb +5 -5
  30. data/lib/keisan/ast/unary_operator.rb +2 -2
  31. data/lib/keisan/ast/unary_plus.rb +2 -2
  32. data/lib/keisan/ast/variable.rb +26 -10
  33. data/lib/keisan/context.rb +5 -5
  34. data/lib/keisan/evaluator.rb +15 -8
  35. data/lib/keisan/function.rb +24 -6
  36. data/lib/keisan/functions/cbrt.rb +1 -1
  37. data/lib/keisan/functions/cos.rb +1 -1
  38. data/lib/keisan/functions/cosh.rb +1 -1
  39. data/lib/keisan/functions/cot.rb +1 -1
  40. data/lib/keisan/functions/coth.rb +1 -1
  41. data/lib/keisan/functions/csc.rb +1 -1
  42. data/lib/keisan/functions/csch.rb +1 -1
  43. data/lib/keisan/functions/default_registry.rb +53 -74
  44. data/lib/keisan/functions/diff.rb +18 -14
  45. data/lib/keisan/functions/erf.rb +15 -0
  46. data/lib/keisan/functions/exp.rb +1 -1
  47. data/lib/keisan/functions/expression_function.rb +15 -21
  48. data/lib/keisan/functions/filter.rb +13 -15
  49. data/lib/keisan/functions/if.rb +14 -20
  50. data/lib/keisan/functions/let.rb +36 -0
  51. data/lib/keisan/functions/map.rb +11 -13
  52. data/lib/keisan/functions/math_function.rb +2 -2
  53. data/lib/keisan/functions/proc_function.rb +10 -6
  54. data/lib/keisan/functions/rand.rb +2 -1
  55. data/lib/keisan/functions/range.rb +74 -0
  56. data/lib/keisan/functions/reduce.rb +12 -14
  57. data/lib/keisan/functions/registry.rb +7 -7
  58. data/lib/keisan/functions/replace.rb +8 -8
  59. data/lib/keisan/functions/sample.rb +2 -1
  60. data/lib/keisan/functions/sec.rb +1 -1
  61. data/lib/keisan/functions/sech.rb +1 -1
  62. data/lib/keisan/functions/sin.rb +1 -1
  63. data/lib/keisan/functions/sinh.rb +1 -1
  64. data/lib/keisan/functions/sqrt.rb +1 -1
  65. data/lib/keisan/functions/tan.rb +1 -1
  66. data/lib/keisan/functions/tanh.rb +1 -1
  67. data/lib/keisan/functions/while.rb +46 -0
  68. data/lib/keisan/parser.rb +121 -79
  69. data/lib/keisan/parsing/assignment.rb +1 -1
  70. data/lib/keisan/parsing/bitwise_and.rb +1 -1
  71. data/lib/keisan/parsing/bitwise_not.rb +1 -1
  72. data/lib/keisan/parsing/bitwise_not_not.rb +1 -1
  73. data/lib/keisan/parsing/bitwise_or.rb +1 -1
  74. data/lib/keisan/parsing/bitwise_xor.rb +1 -1
  75. data/lib/keisan/parsing/curly_group.rb +6 -0
  76. data/lib/keisan/parsing/divide.rb +1 -1
  77. data/lib/keisan/parsing/exponent.rb +1 -1
  78. data/lib/keisan/parsing/function.rb +1 -1
  79. data/lib/keisan/parsing/group.rb +1 -1
  80. data/lib/keisan/parsing/indexing.rb +1 -1
  81. data/lib/keisan/parsing/line_separator.rb +6 -0
  82. data/lib/keisan/parsing/logical_and.rb +1 -1
  83. data/lib/keisan/parsing/logical_equal.rb +1 -1
  84. data/lib/keisan/parsing/logical_greater_than.rb +1 -1
  85. data/lib/keisan/parsing/logical_greater_than_or_equal_to.rb +1 -1
  86. data/lib/keisan/parsing/logical_less_than.rb +1 -1
  87. data/lib/keisan/parsing/logical_less_than_or_equal_to.rb +1 -1
  88. data/lib/keisan/parsing/logical_not.rb +1 -1
  89. data/lib/keisan/parsing/logical_not_equal.rb +1 -1
  90. data/lib/keisan/parsing/logical_not_not.rb +1 -1
  91. data/lib/keisan/parsing/logical_or.rb +1 -1
  92. data/lib/keisan/parsing/minus.rb +1 -1
  93. data/lib/keisan/parsing/modulo.rb +1 -1
  94. data/lib/keisan/parsing/operator.rb +1 -1
  95. data/lib/keisan/parsing/plus.rb +1 -1
  96. data/lib/keisan/parsing/times.rb +1 -1
  97. data/lib/keisan/parsing/unary_minus.rb +1 -1
  98. data/lib/keisan/parsing/unary_operator.rb +1 -1
  99. data/lib/keisan/parsing/unary_plus.rb +1 -1
  100. data/lib/keisan/repl.rb +1 -1
  101. data/lib/keisan/tokenizer.rb +4 -9
  102. data/lib/keisan/tokens/group.rb +3 -1
  103. data/lib/keisan/tokens/line_separator.rb +11 -0
  104. data/lib/keisan/variables/default_registry.rb +0 -5
  105. data/lib/keisan/variables/registry.rb +7 -7
  106. data/lib/keisan/version.rb +1 -1
  107. metadata +27 -2
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- -Keisan::AST::Function.new([argument], "sin")
11
+ -AST::Function.new([argument], "sin")
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- Keisan::AST::Function.new([argument], "sinh")
11
+ AST::Function.new([argument], "sinh")
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- -Keisan::AST::Exponent.new([Keisan::AST::Function.new([argument], "sin"), -2])
11
+ -AST::Exponent.new([AST::Function.new([argument], "sin"), -2])
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- -Keisan::AST::Exponent.new([Keisan::AST::Function.new([argument], "sinh"), -2])
11
+ -AST::Exponent.new([AST::Function.new([argument], "sinh"), -2])
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- -Keisan::AST::Function.new([argument], "cos") * Keisan::AST::Exponent.new([Keisan::AST::Function.new([argument], "sin"), -2])
11
+ -AST::Function.new([argument], "cos") * AST::Exponent.new([AST::Function.new([argument], "sin"), -2])
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- -Keisan::AST::Function.new([argument], "cosh") * Keisan::AST::Exponent.new([Keisan::AST::Function.new([argument], "sinh"), -2])
11
+ -AST::Function.new([argument], "cosh") * AST::Exponent.new([AST::Function.new([argument], "sinh"), -2])
12
12
  end
13
13
  end
14
14
  end
@@ -1,6 +1,10 @@
1
+ require_relative "let"
2
+
1
3
  require_relative "if"
4
+ require_relative "while"
2
5
  require_relative "diff"
3
6
  require_relative "replace"
7
+ require_relative "range"
4
8
  require_relative "map"
5
9
  require_relative "filter"
6
10
  require_relative "reduce"
@@ -8,6 +12,7 @@ require_relative "rand"
8
12
  require_relative "sample"
9
13
  require_relative "math_function"
10
14
  require_relative "cmath_function"
15
+ require_relative "erf"
11
16
  require_relative "exp"
12
17
  require_relative "log"
13
18
  require_relative "sin"
@@ -40,43 +45,27 @@ module Keisan
40
45
  private
41
46
 
42
47
  def self.register_defaults!(registry)
43
- registry.register!(:if, Keisan::Functions::If.new, force: true)
44
- registry.register!(:diff, Keisan::Functions::Diff.new, force: true)
45
- registry.register!(:replace, Keisan::Functions::Replace.new, force: true)
46
- registry.register!(:map, Keisan::Functions::Map.new, force: true)
47
- registry.register!(:collect, Keisan::Functions::Map.new, force: true)
48
- registry.register!(:filter, Keisan::Functions::Filter.new, force: true)
49
- registry.register!(:select, Keisan::Functions::Filter.new, force: true)
50
- registry.register!(:reduce, Keisan::Functions::Reduce.new, force: true)
51
- registry.register!(:inject, Keisan::Functions::Reduce.new, force: true)
52
-
53
- register_builtin_math!(registry)
48
+ registry.register!(:let, Let.new, force: true)
49
+
50
+ registry.register!(:if, If.new, force: true)
51
+ registry.register!(:while, While.new, force: true)
52
+ registry.register!(:diff, Diff.new, force: true)
53
+ registry.register!(:replace, Replace.new, force: true)
54
+ registry.register!(:map, Map.new, force: true)
55
+ registry.register!(:collect, Map.new, force: true)
56
+ registry.register!(:filter, Filter.new, force: true)
57
+ registry.register!(:select, Filter.new, force: true)
58
+ registry.register!(:reduce, Reduce.new, force: true)
59
+ registry.register!(:inject, Reduce.new, force: true)
60
+
61
+ register_math!(registry)
54
62
  register_array_methods!(registry)
55
63
  register_random_methods!(registry)
64
+ end
56
65
 
57
- registry.register!(:exp, Keisan::Functions::Exp.new, force: true)
58
- registry.register!(:log, Keisan::Functions::Log.new, force: true)
59
-
60
- registry.register!(:sin, Keisan::Functions::Sin.new, force: true)
61
- registry.register!(:cos, Keisan::Functions::Cos.new, force: true)
62
- registry.register!(:tan, Keisan::Functions::Tan.new, force: true)
63
- registry.register!(:cot, Keisan::Functions::Cot.new, force: true)
64
- registry.register!(:sec, Keisan::Functions::Sec.new, force: true)
65
- registry.register!(:csc, Keisan::Functions::Csc.new, force: true)
66
-
67
- registry.register!(:sinh, Keisan::Functions::Sinh.new, force: true)
68
- registry.register!(:cosh, Keisan::Functions::Cosh.new, force: true)
69
- registry.register!(:tanh, Keisan::Functions::Tanh.new, force: true)
70
- registry.register!(:coth, Keisan::Functions::Coth.new, force: true)
71
- registry.register!(:sech, Keisan::Functions::Sech.new, force: true)
72
- registry.register!(:csch, Keisan::Functions::Csch.new, force: true)
73
-
74
- registry.register!(:sqrt, Keisan::Functions::Sqrt.new, force: true)
75
- registry.register!(:cbrt, Keisan::Functions::Cbrt.new, force: true)
76
-
77
- registry.register!(:abs, Keisan::Functions::Abs.new, force: true)
78
- registry.register!(:real, Keisan::Functions::Real.new, force: true)
79
- registry.register!(:imag, Keisan::Functions::Imag.new, force: true)
66
+ def self.register_math!(registry)
67
+ register_builtin_math!(registry)
68
+ register_custom_math!(registry)
80
69
  end
81
70
 
82
71
  def self.register_builtin_math!(registry)
@@ -92,54 +81,44 @@ module Keisan
92
81
  end
93
82
  end
94
83
 
84
+ CUSTOM_MATH_FUNCTIONS = %i(erf exp log sin cos tan cot sec csc sinh cosh tanh coth sech csch sqrt cbrt abs real imag).freeze
85
+
86
+ def self.register_custom_math!(registry)
87
+ factorial = Proc.new {|n|
88
+ (1..n).inject(1) do |res, i|
89
+ res * i
90
+ end
91
+ }
92
+ nPk = Proc.new {|n, k|
93
+ factorial.call(n) / factorial.call(n-k)
94
+ }
95
+ nCk = Proc.new {|n, k|
96
+ factorial.call(n) / factorial.call(k) / factorial.call(n-k)
97
+ }
98
+
99
+ registry.register!(:factorial, factorial, force: true)
100
+ registry.register!(:nPk, nPk, force: true)
101
+ registry.register!(:permute, nPk, force: true)
102
+ registry.register!(:nCk, nCk, force: true)
103
+ registry.register!(:choose, nCk, force: true)
104
+
105
+ CUSTOM_MATH_FUNCTIONS.each do |method|
106
+ klass = Keisan::Functions.const_get(method.to_s.capitalize)
107
+ registry.register!(method, klass.new, force: true)
108
+ end
109
+ end
110
+
95
111
  def self.register_array_methods!(registry)
96
112
  %i(min max size flatten reverse).each do |method|
97
113
  registry.register!(method, Proc.new {|a| a.send(method)}, force: true)
98
114
  end
99
115
 
100
- # range(10) => Integers from 0 inclusive to 10 exclusively
101
- # range(5, 15) => Integers from 5 inclusive to 15 exclusive
102
- # range(10, -1, -2) => Integers from 10 inclusive to -1 exclusive, decreasing by twos
103
- # i.e.: [10, 8, 6, 4, 2, 0]
104
- registry.register!("range", Proc.new {|*args|
105
- case args.count
106
- when 1
107
- (0...args[0]).to_a
108
- when 2
109
- (args[0]...args[1]).to_a
110
- when 3
111
- current = args[0]
112
- final = args[1]
113
- shift = args[2]
114
-
115
- if shift == 0 or !shift.is_a?(Integer)
116
- raise Keisan::Exceptions::InvalidFunctionError.new("range's 3rd argument must be non-zero integer")
117
- end
118
-
119
- result = []
120
-
121
- if shift > 0
122
- while current < final
123
- result << current
124
- current += shift
125
- end
126
- else
127
- while current > final
128
- result << current
129
- current += shift
130
- end
131
- end
132
-
133
- result
134
- else
135
- raise Keisan::Exceptions::InvalidFunctionError.new("range takes 1 to 3 arguments")
136
- end
137
- }, force: true)
116
+ registry.register!("range", Functions::Range.new, force: true)
138
117
  end
139
118
 
140
119
  def self.register_random_methods!(registry)
141
- registry.register!(:rand, Keisan::Functions::Rand.new, force: true)
142
- registry.register!(:sample, Keisan::Functions::Sample.new, force: true)
120
+ registry.register!(:rand, Rand.new, force: true)
121
+ registry.register!(:sample, Sample.new, force: true)
143
122
  end
144
123
  end
145
124
  end
@@ -1,23 +1,26 @@
1
1
  module Keisan
2
2
  module Functions
3
- class Diff < Keisan::Function
3
+ class Diff < Function
4
4
  def initialize
5
+ super("diff", -1)
5
6
  @name = "diff"
6
7
  end
7
8
 
8
9
  def value(ast_function, context = nil)
9
- context ||= Keisan::Context.new
10
+ validate_arguments!(ast_function.children.count)
11
+ context ||= Context.new
10
12
  evaluation = evaluate(ast_function, context)
11
13
 
12
14
  if is_ast_derivative?(evaluation)
13
- raise Keisan::Exceptions::NonDifferentiableError.new
15
+ raise Exceptions::NonDifferentiableError.new
14
16
  else
15
17
  evaluation.value(context)
16
18
  end
17
19
  end
18
20
 
19
21
  def evaluate(ast_function, context = nil)
20
- context ||= Keisan::Context.new
22
+ validate_arguments!(ast_function.children.count)
23
+ context ||= Context.new
21
24
  function, variables = function_and_variables(ast_function)
22
25
  local = context_from(variables, context)
23
26
 
@@ -30,7 +33,7 @@ module Keisan
30
33
  end
31
34
 
32
35
  case result
33
- when Keisan::AST::Function
36
+ when AST::Function
34
37
  result.name == "diff" ? result : result.simplify(context)
35
38
  else
36
39
  result.simplify(context)
@@ -38,9 +41,10 @@ module Keisan
38
41
  end
39
42
 
40
43
  def simplify(ast_function, context = nil)
41
- raise Keisan::Exceptions::InternalError.new("received non-diff function") unless ast_function.name == "diff"
44
+ validate_arguments!(ast_function.children.count)
45
+ raise Exceptions::InternalError.new("received non-diff function") unless ast_function.name == "diff"
42
46
  function, variables = function_and_variables(ast_function)
43
- context ||= Keisan::Context.new
47
+ context ||= Context.new
44
48
  local = context_from(variables, context)
45
49
 
46
50
  result = variables.inject(function.simplify(local)) do |result, variable|
@@ -52,7 +56,7 @@ module Keisan
52
56
  end
53
57
 
54
58
  case result
55
- when Keisan::AST::Function
59
+ when AST::Function
56
60
  result.name == "diff" ? result : result.simplify(context)
57
61
  else
58
62
  result.simplify(context)
@@ -62,7 +66,7 @@ module Keisan
62
66
  private
63
67
 
64
68
  def is_ast_derivative?(node)
65
- node.is_a?(Keisan::AST::Function) && node.name == name
69
+ node.is_a?(AST::Function) && node.name == name
66
70
  end
67
71
 
68
72
  def differentiate(node, variable, context)
@@ -71,7 +75,7 @@ module Keisan
71
75
  else
72
76
  return AST::Number.new(0)
73
77
  end
74
- rescue Keisan::Exceptions::NonDifferentiableError => e
78
+ rescue Exceptions::NonDifferentiableError => e
75
79
  return AST::Function.new(
76
80
  [node, variable],
77
81
  "diff"
@@ -79,14 +83,14 @@ module Keisan
79
83
  end
80
84
 
81
85
  def function_and_variables(ast_function)
82
- unless ast_function.is_a?(Keisan::AST::Function) && ast_function.name == name
83
- raise Keisan::Exceptions::InvalidFunctionError.new("Must receive diff function")
86
+ unless ast_function.is_a?(AST::Function) && ast_function.name == name
87
+ raise Exceptions::InvalidFunctionError.new("Must receive diff function")
84
88
  end
85
89
 
86
90
  variables = ast_function.children[1..-1]
87
91
 
88
92
  unless variables.all? {|var| var.is_a?(AST::Variable)}
89
- raise Keisan::Exceptions::InvalidFunctionError.new("Diff must differentiate with respect to variables")
93
+ raise Exceptions::InvalidFunctionError.new("Diff must differentiate with respect to variables")
90
94
  end
91
95
 
92
96
  [
@@ -96,7 +100,7 @@ module Keisan
96
100
  end
97
101
 
98
102
  def context_from(variables, context = nil)
99
- context ||= Keisan::Context.new(shadowed: variables.map(&:name))
103
+ context ||= Context.new(shadowed: variables.map(&:name))
100
104
  context.spawn_child(shadowed: variables.map(&:name))
101
105
  end
102
106
  end
@@ -0,0 +1,15 @@
1
+ module Keisan
2
+ module Functions
3
+ class Erf < MathFunction
4
+ def initialize
5
+ super("erf")
6
+ end
7
+
8
+ protected
9
+
10
+ def self.derivative(argument)
11
+ 2/Math.sqrt(Math::PI) * AST::Function.new([-argument**2], "exp")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,7 +8,7 @@ module Keisan
8
8
  protected
9
9
 
10
10
  def self.derivative(argument)
11
- Keisan::AST::Function.new([argument], "exp")
11
+ AST::Function.new([argument], "exp")
12
12
  end
13
13
  end
14
14
  end
@@ -1,17 +1,17 @@
1
1
  module Keisan
2
2
  module Functions
3
- class ExpressionFunction < Keisan::Function
3
+ class ExpressionFunction < Function
4
4
  attr_reader :arguments, :expression
5
5
 
6
6
  def initialize(name, arguments, expression, transient_definitions)
7
- super(name)
7
+ super(name, arguments.count)
8
8
  @expression = expression.deep_dup
9
9
  @arguments = arguments
10
10
  @transient_definitions = transient_definitions
11
11
  end
12
12
 
13
13
  def call(context, *args)
14
- verify_argument_size!(args.count)
14
+ validate_arguments!(args.count)
15
15
 
16
16
  local = local_context_for(context)
17
17
  arguments.each.with_index do |arg_name, i|
@@ -22,17 +22,17 @@ module Keisan
22
22
  end
23
23
 
24
24
  def value(ast_function, context = nil)
25
- verify_argument_size!(ast_function.children.count)
25
+ validate_arguments!(ast_function.children.count)
26
26
 
27
- context ||= Keisan::Context.new
27
+ context ||= Context.new
28
28
  argument_values = ast_function.children.map {|child| child.value(context)}
29
29
  call(context, *argument_values)
30
30
  end
31
31
 
32
32
  def evaluate(ast_function, context = nil)
33
- verify_argument_size!(ast_function.children.count)
33
+ validate_arguments!(ast_function.children.count)
34
34
 
35
- context ||= Keisan::Context.new
35
+ context ||= Context.new
36
36
  local = local_context_for(context)
37
37
 
38
38
  argument_values = ast_function.children.map {|child| child.evaluate(context)}
@@ -41,18 +41,18 @@ module Keisan
41
41
  local.register_variable!(arg_name, argument_values[i].evaluate(context))
42
42
  end
43
43
 
44
- expression.evaluate(local)
44
+ expression.evaluated(local)
45
45
  end
46
46
 
47
47
  def simplify(ast_function, context = nil)
48
- verify_argument_size!(ast_function.children.count)
48
+ validate_arguments!(ast_function.children.count)
49
49
 
50
50
  ast_function.instance_variable_set(
51
51
  :@children,
52
52
  ast_function.children.map {|child| child.evaluate(context)}
53
53
  )
54
54
 
55
- if ast_function.children.all? {|child| child.is_a?(Keisan::AST::ConstantLiteral)}
55
+ if ast_function.children.all? {|child| child.is_a?(AST::ConstantLiteral)}
56
56
  value(ast_function, context).to_node.simplify(context)
57
57
  else
58
58
  ast_function
@@ -66,7 +66,7 @@ module Keisan
66
66
  # dx(t)/dt * f_x(x(t), y(t)) + dy(t)/dt * f_y(x(t), y(t)),
67
67
  # where f_x and f_y are the x and y partial derivatives respectively.
68
68
  def differentiate(ast_function, variable, context = nil)
69
- verify_argument_size!(ast_function.children.count)
69
+ validate_arguments!(ast_function.children.count)
70
70
 
71
71
  local = local_context_for(context)
72
72
 
@@ -78,10 +78,10 @@ module Keisan
78
78
  child.differentiate(variable, context)
79
79
  end
80
80
 
81
- Keisan::AST::Plus.new(
81
+ AST::Plus.new(
82
82
  argument_derivatives.map.with_index {|argument_derivative, i|
83
83
  partial_derivative = partial_derivatives[i].replace(argument_variables[i], argument_values[i])
84
- Keisan::AST::Times.new([argument_derivative, partial_derivative])
84
+ AST::Times.new([argument_derivative, partial_derivative])
85
85
  }
86
86
  )
87
87
  end
@@ -89,7 +89,7 @@ module Keisan
89
89
  private
90
90
 
91
91
  def argument_variables
92
- @argument_variables ||= arguments.map {|argument| Keisan::AST::Variable.new(argument)}
92
+ @argument_variables ||= arguments.map {|argument| AST::Variable.new(argument)}
93
93
  end
94
94
 
95
95
  def partial_derivatives
@@ -98,14 +98,8 @@ module Keisan
98
98
  end
99
99
  end
100
100
 
101
- def verify_argument_size!(argument_size)
102
- unless @arguments.count == argument_size
103
- raise Keisan::Exceptions::InvalidFunctionError.new("Invalid number of arguments for #{name} function")
104
- end
105
- end
106
-
107
101
  def local_context_for(context = nil)
108
- context ||= Keisan::Context.new
102
+ context ||= Context.new
109
103
  context.spawn_child(definitions: @transient_definitions, shadowed: @arguments, transient: true)
110
104
  end
111
105
  end