As a Java developer exploring Scala, I am relating what I found when trying to learn this language through calling a familiar Java library. In part 1 we covered the basics, now we’ll look at how user-defined functions are used to create solutions to unique problems and how the charting functionality in JMSL lets you visualize results.

**User-defined functions**

User-defined functions are a key aspect of any numerical library. While much mathematical and statistical analysis can be performed by passing data, many scenarios require a solution to a specific problem, unique to each user. Root solving and optimization are the obvious examples where the user has a specific equation form, with specific coefficients, that needs to be solved for their use case. The JMSL Library uses Interfaces to allow users to define their functions. The API defines the interface name that needs to be implemented including the method signature. Once the user has that in place, internally the function they defined is called repeatedly by the solver algorithm.

For the first example, the JMSL solve algorithm ZerosFunction is used. This class solves for the roots of a function specified by the user. In Java one simply creates an object for the interface to implement. In this case, the interface is named ZeroSystem.Function, which requires a public method named `f`

that accepts two double arrays, returning void. There are variations across the JMSL Library classes that utilize interfaces for user-defined functions. Some require values to be returned, but in this case the user is literally implementing the function `f(x)`

where the `x`

values are passed into the function and values of `f`

are computed.

The function in the documentation example to solve is the following system of equations:

*f*

_{1}(x) = x_{1}+ e^{x1-1}+ (x_{2}+ x_{3})^{2}– 27*f*

_{2}(x) = e^{x2-2}/ x_{1}+ x_{3}^{2}– 10*f*

_{3}(x) = x_{3}+ sin(x_{2}-2) + x_{2}^{2}– 7In Java, this user-defined function is implemented as follows:

```
ZeroSystem.Function fcn = new ZeroSystem.Function() {
public void f(double x[], double f[]) {
f[0] = x[0] + Math.exp(x[0] - 1.0)
+ (x[1] + x[2]) * (x[1] + x[2]) - 27.0;
f[1] = Math.exp(x[1] - 2.0) / x[0] + x[2] * x[2] - 10.0;
f[2] = x[2] + Math.sin(x[1] - 2.0) + x[1] * x[1] - 7.0;
}
};
```

The translation to Scala is almost exactly the same:

```
val fcn = new ZeroSystem.Function {
def f(x: Array[Double], f: Array[Double]) {
f[0] = x[0] + Math.exp(x[0] - 1.0)
+ (x[1] + x[2]) * (x[1] + x[2]) - 27.0;
f[1] = Math.exp(x[1] - 2.0) / x[0] + x[2] * x[2] - 10.0;
f[2] = x[2] + Math.sin(x[1] - 2.0) + x[1] * x[1] - 7.0;
}
};
```

The rest of the example creates the actual ZeroSystem object, sets an initial guess, then solves for the roots and prints them out:

```
val zs = new ZeroSystem(3)
zs.setGuess(Array(4.0, 4.0, 4.0))
val zsx = zs.solve(fcn)
new PrintMatrix("ZeroSystem solution").print(zsx)
ZeroSystem solution
0
0 1
1 2
2 3
```

Interestingly a `trait`

can also be defined in Scala and used similarly. This method is a little more verbose and less Java-like, but some users may prefer it. To avoid repetition, the solver MinUncon is used below. This function is an unconstrained minimization algorithm, solving the function *f(x)*=*e ^{x}*-5

*x*:

```
trait muFcn extends MinUncon with MinUncon.Function {
def f(x: Double): Double = {
Math.exp(x) - 5.0 * x
}
}
val mu = new MinUncon with muFcn
mu.setGuess(0.0)
mu.setAccuracy(0.00001)
println("\nMinUncon solution = " + mu.computeMin(mu))
MinUncon solution = 1.6094353603002598
```

The `trait`

is defined first, explicitly declaring the class being extended and the interface being implemented. When the MinUncon object is instantiated, the trait is referenced using the `with`

keyword. The function call `mu.computeMin(mu)`

looks recursive, but the `mu`

object itself is implementing the interface. This is consistent with the Java technique of declaring the class to implement the interface, then passing in `this`

as an argument to the `computeMin()`

method.

**Charting**

The JMSL Library includes charting functionality along with the numerical algorithms. Generally, the chart would be part of a larger user application and use the JPanelChart as a container, used wherever a JPanel would be used. A ChartServlet class is provided for JSP applications, and 3D graphics are supported through Java3D. For this example test with Scala, things are kept simple by using the JFrameChart, which behaves like a JFrame including its own menu bar.

```
object MyChart extends JFrameChart {
var a = new AxisXY(this.getChart)
var d = new Data(a, Array(3.0, 6.0, 8.0, 2.0, 4.0))
var ann = new Annotation(a, "Scala!", 3.5, 5.5)
ann.setTextColor(java.awt.Color.blue)
}
MyChart.setVisible(true)
```

This program creates a singleton object, so there’s no need to instantiate anything and the `setVisible()`

method is called on the object rather than an instance of it. An annotation is included on the graph using chart coordinates to position the text. The output is the following image:

**Summary**

The JMSL Numerical Library is used to explore the features of Scala and cross-language functionality. Static methods, instance classes, user-defined function and charting are all shown through examples. As Java developer with no Scala knowledge, the experience is uncomplicated given all the parallels between these languages.

A complete Scala program including all these examples can be found below.

**Full code example**

```
import com.imsl.math.{Sfun, LU, Bessel, ZeroPolynomial}
import com.imsl.math.{ZerosFunction, ZeroSystem}
import com.imsl.math.{MinUncon, MinConGenLin}
import com.imsl.chart._
object HelloJmsl {
def main(args: Array[String]): Unit = {
/* easy case of static method */
println("\n -- Static method call --")
val erf2 = Sfun.erf(0.5)
println("erf(0.5) = " + erf2)
/* instantiate a class with vector input and output */
println("\n -- Class instance --")
val zp = new ZeroPolynomial
val coef = Array(1.0, 2.0, 5.0)
val roots = zp.computeRoots(coef)
println("x_1 = " + roots(0))
println("x_2 = " + roots(1))
/* instantiate a class that requires a matrix */
println("\n -- Class instance --")
val a = Array(
Array(1.0, 3.0, 3.0),
Array(1.0, 3.0, 4.0),
Array(1.0, 4.0, 3.0))
val b = Array(12.0, 13.0, 14.0)
val lu = new LU(a)
val x = lu.solve(b)
println("LU answer = " + x(0) + "\t" + x(1) + "\t" + x(2))
new com.imsl.math.PrintMatrix("x").print(x)
println("LU condition number = " + lu.condition(a))
/* User-defined function */
println("\n -- User-defined function --")
val zsFcn = new ZeroSystem.Function {
def f(x: Array[Double], f: Array[Double]) {
f(0) = x(0) + Math.exp(x(0) - 1.0) + (x(1) + x(2)) * (x(1) + x(2)) - 27.0
f(1) = Math.exp(x(1) - 2.0) / x(0) + x(2) * x(2) - 10.0
f(2) = x(2) + Math.sin(x(1) - 2.0) + x(1) * x(1) - 7.0
}
}
var zs = new ZeroSystem(3) // with zsFcn
zs.setGuess(Array(4.0, 4.0, 4.0))
var zsx = zs.solve(zsFcn)
new com.imsl.math.PrintMatrix("ZeroSystem solution").print(zsx)
/* Using a trait for a user-defined function */
println("\n -- User-defined function with a trait --")
trait muFcn extends MinUncon with MinUncon.Function {
def f(x: Double): Double = {
Math.exp(x) - 5.0 * x
}
}
val mu = new MinUncon with muFcn
mu.setGuess(0.0)
mu.setAccuracy(0.00001)
println("\nMinUncon solution = " + mu.computeMin(mu))
/* charting example */
println("\n -- Chart example (blocking window should open) --")
object MyChart extends JFrameChart {
var a = new AxisXY(this.getChart)
var d = new Data(a, Array(3.0, 6.0, 8.0, 2.0, 4.0))
var ann = new Annotation(a, "Scala!", 3.5, 5.5)
ann.setTextColor(java.awt.Color.blue)
}
// note that this object (singleton instance of a class) but it
// could be a class then you'd need to instantiate it with
// val c = new MyChart and display with c.setVisible(true)
MyChart.setVisible(true)
}
}
```