Back to Smile

Computer Algebra System

studio/src/universal/notebooks/cas.ipynb

6.1.02.5 KB
Original Source

Computer Algebra System

A computer algebra system (CAS) has the ability to manipulate mathematical expressions in a way similar to the traditional manual computations of mathematicians and scientists.

The symbolic manipulations supported include:

  • simplification to a smaller expression or some standard form, including automatic simplification with assumptions and simplification with constraints
  • substitution of symbols or numeric values for certain expressions
  • change of form of expressions: expanding products and powers, partial and full factorization, rewriting as partial fractions, constraint satisfaction, rewriting trigonometric functions as exponentials, transforming logic expressions, etc.
  • partial and total differentiation
  • matrix operations including products, inverses, etc.
scala
import smile.cas._

The CAS module is self-contained. There is no need to import other Smile modules. In the below, we first define a variable x. Then we define an expression e, which is a function of x. For demo purpose, we include some redundant elements, which will be simplified away automatically.

scala
val x = Var("x")

val e = 0 * x**2 + 1 * x**1 + 1 * x**2 * cot(x**3)
println(e)

We can also derive the derivative of e with respect to x.

scala
val d = e.d(x)
println(d)

To evaluate an expression, simply apply it on a map of values.

scala
d("x" -> Val(1))

In fact, we may substitute the variables with other abstract expression rather than only values.

scala
val y = x + 2
println(d("x" -> y))

An expression may contain multiple variables.

scala
val y = Var("y")
val e = sin(x) + cos(y)
println(e)
scala
println(e.d(x), e.d(y))

Beyond scalars, we can define vector variables.

scala
val x = VectorVar("x")
val y = VectorVar("y")

Note that the dimension of vector, if not specified, is a constant value n.

scala
val a = Const("a")
val b = Const("b")
val e = a * x + b * y
println(e)

In the above example, we define two constant yet abstract values a and b. Therefore, they will be treated independently from variables when we derive derivative.

scala
println(e.d(x), e.d(y))

Note that the derivate of vector with respect to a vector is matrix.

scala
val dot = x * y
println(dot)

As shown, the dot product (or inner product) is a scalar. The derivative of a scalar with respect to a vector, i.e. the gradient, is a vector.

scala
dot.d(x)

With operator *~, we can derive the outer product.

scala
val outer = (2 *x) *~ (3 * y)
println(outer)