Module: Maxima

Defined in:
lib/maxima/core.rb,
lib/maxima/unit.rb,
lib/maxima/float.rb,
lib/maxima/helper.rb,
lib/maxima/boolean.rb,
lib/maxima/command.rb,
lib/maxima/complex.rb,
lib/maxima/version.rb,
lib/maxima/function.rb,
lib/maxima/rational.rb,
lib/maxima/histogram.rb,
lib/maxima/polynomial.rb

Defined Under Namespace

Modules: Helper Classes: Boolean, Command, Complex, Float, Function, Histogram, Polynomial, Rational, Unit

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.bin_op(e_1, e_2, bin_op) ⇒ Object



2
3
4
# File 'lib/maxima/core.rb', line 2

def self.bin_op(e_1, e_2, bin_op)
  Maxima::Function.new("((#{Maxima.mformat(e_1)}) #{bin_op} (#{Maxima.mformat(e_2)}))")
end

.cobyla(minimize_function, variables, constraint_function, initial_guess) ⇒ Object



6
7
8
9
10
11
12
13
14
15
# File 'lib/maxima/core.rb', line 6

def self.cobyla(minimize_function, variables, constraint_function, initial_guess)
  Command.output(variables => Unit) do |c|
    initial_guess = mformat(initial_guess)

    c.dependencies << "cobyla"

    c.let :output, "fmin_cobyla(#{minimize_function}, #{mformat(variables)}, #{initial_guess},constraints = #{constraint_function})"
    c.let variables, "sublis(output[1], #{variables})"
  end
end

.Complex(real, imaginary) ⇒ Object



3
4
5
# File 'lib/maxima/complex.rb', line 3

def self.Complex(real, imaginary)
  Complex.new(real, imaginary)
end

.diff(function, v: "x") ⇒ Object



34
35
36
37
38
39
# File 'lib/maxima/core.rb', line 34

def self.diff(function, v: "x")
  Command.output(diff: Function) do |c|
    c.let :function, function
    c.let :diff, "derivative(function, #{v})"
  end
end

.equivalence(expression_one, expression_two) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/maxima/core.rb', line 82

def self.equivalence(expression_one, expression_two)
  Command.output(:is_equal => Boolean) do |c|
    formatted_expression_one = mformat(expression_one)
    formatted_expression_two = mformat(expression_two)

    c.let :is_equal, "is(equal(#{formatted_expression_one}, #{formatted_expression_two}))"
  end
end

.Float(real) ⇒ Object



3
4
5
# File 'lib/maxima/float.rb', line 3

def self.Float(real)
  Float.new(real)
end

.integrate(function, t0 = nil, t1 = nil, v: "x") ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/maxima/core.rb', line 25

def self.integrate(function, t0 = nil, t1 = nil, v: "x")
  expression = (t0 && t1) ? "integrate(function, #{v}, #{t0}, #{t1})" : "integrate(function, #{v})"

  Command.output(integral: Function) do |c|
    c.let :function, function
    c.let :integral, expression
  end
end

.interpolate(array) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/maxima/core.rb', line 17

def self.interpolate(array)
  Command.output(lagrangian: Function) do |c|
    c.dependencies << "interpol"
    c.let :array, array.to_a
    c.let_simplified :lagrangian, "lagrange(array)"
  end
end

.lagrangian(minimize_function, variables, constraint_function, initial_guess, iterations: 5) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/maxima/core.rb', line 91

def self.lagrangian(minimize_function, variables, constraint_function, initial_guess, iterations: 5)
  Command.output(variables => Unit) do |c|
    initial_guess       = mformat(initial_guess)
    constraint_function = mformat(Array(constraint_function))
    optional_args       = mformat(niter: iterations)

    c.dependencies << "lbfgs"
    c.dependencies << "augmented_lagrangian"

    c.let :output, "augmented_lagrangian_method(#{minimize_function}, #{variables}, #{constraint_function}, #{initial_guess}, #{optional_args})"
    c.let variables, "sublis(output[1], #{variables})"
  end
end

.lsquares_estimation(points, variables, equation, outputs, equation_for_mse: equation) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/maxima/core.rb', line 64

def self.lsquares_estimation(points, variables, equation, outputs, equation_for_mse: equation)
  Command.output(outputs => Complex, :mse => Float) do |c|
    formatted_points    = points.map { |a| mformat(a) }.join(",")
    formatted_variables = mformat(variables)
    formatted_outputs   = mformat(outputs)

    c.dependencies << "lsquares"
    c.let :M, "matrix(#{formatted_points})"
    c.let :lsquares_estimation, "lsquares_estimates(M, #{formatted_variables}, #{equation}, #{formatted_outputs})"
    if outputs.count == 1
      c << "map (lhs, lsquares_estimation) :: map (rhs, lsquares_estimation)"
    else
      c << "map (lhs, lsquares_estimation[1]) :: map (rhs, lsquares_estimation[1])"
    end
    c.let :mse, "lsquares_residual_mse(M, #{formatted_variables}, #{equation_for_mse}, first (lsquares_estimation))"
  end
end

.mformat(variable) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/maxima/core.rb', line 105

def self.mformat(variable)
  case variable
  when String, Symbol
    variable # the only truly `valid` input is a string
  when Hash
    variable.map do |key,value|
      "#{mformat(key)} = #{mformat(value)}"
    end.join(", ")
  when Array
    "[" + variable.map { |v| mformat(v) }.join(",") + "]"
  when ::Complex
    mformat Complex.new(variable, variable.real, variable.imag)
  when Numeric
    mformat Float(variable)
  when Complex, Float, Function
    variable.to_maxima_input
  when nil
    throw :cannot_format_nil
  else
    variable
  end
end

.plot(*maxima_objects, from_x: nil, from_y: nil) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/maxima/core.rb', line 41

def self.plot(*maxima_objects, from_x: nil, from_y: nil)
  maxima_objects << [[from_x.min, 0], [from_x.max, 0]] if from_x
  maxima_objects << [[0, from_y.min], [0, to_y.max]] if from_y

  maxima_objects = maxima_objects.map do |k|
    if k.respond_to?(:to_gnu_plot)
      k.to_gnu_plot
    elsif k.is_a?(Array) && !k.first.is_a?(String)
      [*k.transpose, w: "points"]
    else
      k
    end
  end

  Helper.stfu do
    Numo.gnuplot do |c|
      c.debug_on
      c.set title: "Maxima Plot"
      c.plot(*maxima_objects)
    end
  end
end

.solve_polynomial(equations, variables_to_solve_for, ignore: nil, real_only: false) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/maxima/core.rb', line 128

def self.solve_polynomial(equations, variables_to_solve_for, ignore: nil, real_only: false)
  # regex match extract
  output = Command
             .with_options(real_only: real_only)
             .output(output: Unit) do |c|
    variables = mformat(Array(variables_to_solve_for))
    equations = mformat(Array(equations))

    c.let :output, "algsys(#{equations},#{variables})"
  end

  output = output[:output]

  variables_to_solve_for -= Array(ignore)

  variable_regexes = variables_to_solve_for.map do |variable|
    "#{variable}=(-?.*?)(?:\,|\\])"
  end

  regex = Regexp.new(variable_regexes.reduce(&:+))

  output = output.to_s.gsub(" ", "")

  output.scan(regex).map { |row| variables_to_solve_for.zip(row.map { |v| Unit.parse(v) }).to_h }
end