Table of Contents
SCaVis can be used to evaluate, plot, simplify functions. There are several approaches to work with parametric or non-parametric functions using SCaVis Java API:
- User 2D/3D function plotter from SCaVis IDE (see the “Tools” menu)
- Simplify and plot functions using ether Octave or Matlab syntax. See the section Symbolic calculation for detail. Plotting functions in such approach is a bit too simplistic and there is no good integration with Java API and data structures
- Use the full-blown SCaVis Java libraries to create parametric, non-parametric, special functions as they are provided by Java API. One can also integrate, differentiate and simplify such functions. In this case one can use the Java language, or any Java scripting languages (such as Jython or BeanShell). There is complete integration with data structures API and functions can be plotted in 2D/3D using several powerful interactive canvaces.
In this section we will discuss the third option as it is the most flexible for integration with Java libraries. We will start with simple analytical functions with one variable (“x”) and then will consider more complicated cases with several variables (“y”, “z”). Finally, we will show how to make function of arbitrary complexity with any number of variables
Functions with one variable
Functions can be defined using either strings or programically. First we will discuss how to show functions using strings and then we will show other, more flexible methods.
We will start this tutorial with a simple example of how to create and display a function with one and only one variable (“x”). First, let us create an object representing a function:
Such functions are represented by the Java class F1D (1D means one-dimensional function).
>>> from jhplot import * >>> f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x")
Here the input function is given by
One can evaluate this function at a certain point, say at 10, as:
>>> print f1.eval(10) 0.270670566473
To draw the function, one should specify limits during the function initialization (or later using the methods of the Java object F1D. Then one should build a canvas and use the method “draw” to plot the function. In the example below, we define the limits for this function (-2,5) and then we plot it:
1: from jhplot import * 2: f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0) 3: c1 = HPlot("Canvas") 4: c1.visible() 5: c1.setAutoRange() 6: c1.draw(f1)
Here we drop the Python invitation ”»>” since we assume that the this code snippet is executed as a file. Insert these lines to the SCaVis editor and hit the key [F8].
You will see a pop-up window with the output as shown below:
To learn about the method of SCaVis or any Jython or Java objects (like f1 and c1 in the above example):
- Hit <Ctrl>+<Space> after the dot when using the Jython shell prompt (bottom part of the SCaVis IDE).
- When using the SCaVis editor, use the key [F4] (after the dot) which brings up a table with all available Java methods.
- Use Eclipse or NetBean IDE when developing the code using Java. They have their own help system.
- Read the Java API of these classes.
Information about the syntax
Here is a short description about how to define functions. The following table shows the main mathematical operations:
() parenthesis + plus - minus * times / divide ^ raise to a power ** raise to a power
|ceil||nearest upper integer|
|floor||nearest lower integer|
One can also use some predefined constants, such as pi or Pi (the pi value, 3.14..). It is possible to use scientific notation for numbers:
- Snippet from Wikipedia: Scientific notation
Scientific notation (commonly referred to as "standard form") is a way of writing numbers that are too big or too small to be conveniently written in decimal form.
The number is split into a significand / mantissa (y) and exponent (x) of the form 'yEx' which is evaluated as 'y * 10^x'.
Let us give the examples:
from jhplot import * f1=F1D("1+x+(x^2)-(x^3)") # correct answer -1 print f1.eval(2) f1=F1D("1+x+(x*x)-(x*x*x)") # correct answer -1 print f1.eval(2) f1=F1D("1+x+x^2-x^3") # correct answer -1 print f1.eval(2) f1=F1D("1+x+x**2-x**3") # correct answer -1 print f1.eval(2)
The most flexible way to draw functions is to use codding with objects and calling third-party Java libraries directly, instead of using strings with function definitions. This topic will be discussed in Section Non-parametric functions
Symbolic manipulation with functions will be discussed in more details in Section symbolic. Still, one should note that symbolic manipulations can also be done with the F1D functions using Java (or Jython) coding without using any other specialized language (as Matlab or Octave). One can simplify and expand F1D functions. Functions can also be rewritten in terms of elementary functions (log, sqrt, exp). Finally, one can perform some elementary substitutions before attempting to plot a F1D function.
Integration and differentiation
Functions can be numerically integrated. The program supports 5 methods of integration, which vary in evaluation time and accuracy. Below we will integrate the function “cos(x*x)+sin(1/x)*x^2)”
This code integrates the function between 10 and 100 using 5000 integration point (the large the number is, the more accurate the results are). The code also performs some benchmarking which gives you ideas about the accuracy of calculations:
trapezium = 4949.64217622 time (ms)= 31.654937 gauss4 = 4949.64028115 time (ms)= 43.84014 gauss8 = 4949.64028111 time (ms)= 65.27855 richardson = 4949.64028393 time (ms)= 56.030938 simpson = 4949.64014049 time (ms)= 17.634015
Here is a more detailed example showing how to plot several functions using different colors:
1: from java.awt import Color 2: from jhplot import * 3: 4: # first function 5: f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0) 6: f1.setPenDash(4) 7: 8: # second function 9: f2 = F1D("exp(-x*x/50)+pi*x", -2.0, 5.0) 10: f2.setColor(Color.green) 11: f2.setPenWidth(1) 12: 13: # build a canvas with X and Y titles 14: c1 = HPlot("Canvas") 15: c1.setGTitle("2 functions", Color.red) 16: c1.setNameX("X") 17: c1.setNameY("Y") 18: c1.visible() 19: c1.setAutoRange() 20: 21: c1.draw(f1) 22: c1.draw(f2)
Note that we have imported the Java class
java.awt.Color. The output of this script is shown here
You can also plot objects on different pads as shown in the Section graphics.
As any Java object, F1D functions can be saved into files. Read input_output for detailed discussion. In addition, one can convert a function in MathML or Java formats, or just display it as a table with values after evaluation of a function.
>>> from jhplot import F1D >>> f=F1D("10*sin(x)") >>> print f.toMathML() # convert to MathML >>> print f.toJava() # convert to Java code >>> f.toTable() # show a table with X-Y values (the function should be plotted or evaluated before)
Functions in 2 dimensions can be build analogously using the
The example below shows how to construct and evaluate a function 2D:
>>> from jhplot import * >>> f1 = F2D("2*exp(-x*y/50)+sin(pi*x)/y") >>> print f1.eval(10,20) 0.0366312777775
The code prints the answer: 0.270670566473.
Functions in 2 dimensions can be build by analogy using the Java class F3D. The example below shows how to construct and evaluate a function 3D:
>>> from jhplot import * >>> f1 = F3D("2*exp(-x*y/50)+sin(pi*x)/z") >>> print f1.eval(10,20,30) 0.0366312777775
The code prints the answer: 0.0366312777775.
Converting functions to histograms
Histograms can be created from 1D and 2D functions. In the example above, we created a 2D function and then used it to generate 2D histogram. Functions can be converted to histograms with arbitrary number of bins. This often can be used for show selected regions in different color.
Consider the example in which a function is used to create a histogram with fine bins. We use this histogram to highlight a range of our original function.
1: from java.awt import Color 2: from jhplot import * 3: 4: c1 = HPlot("Canvas") 5: c1.setAutoRange() 6: c1.setNameX("X") 7: c1.setNameY("Y") 8: c1.visible() 9: 10: f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0) 11: c1.draw(f1) 12: 13: h=f1.getH1D("Histogram",500,1,5) # histogram with 500 bins between 1 and 5 14: h.setColor(Color.red) 15: h.setFill(1) 16: h.setFillColor(Color.red) 17: c1.draw(h)
Histograms can have arbitrary number of bins, but if the bin number is close to 500 (a typical evaluation step for functions), the difference between function and a histogram will be almost impossible to see.
Plotting in 3D
F2D functions can be shown using 3D canvaces. Two functions can be overlayed and shown on a single plot.
Here is a small example of showing 2 functions in 3D:
1: from jhplot import * 2: c1 = HPlot3D("Canvas") 3: c1.visible() 4: c1.setNameX("X") 5: c1.setNameY("Y") 6: f1 = F2D("2*exp(-x*y/20)+10*sin(pi*x)/y", -2.0, 5.0, -2.0, 5.0) 7: f2 = F2D("4*x*y", -2.0, 5.0, -2.0, 5.0) 8: c1.draw(f1,f2)
The output of this code is:
One can also overlay several different objects. Let us show an example of how to show functions and histograms in3D:
The code used to generate this image is given below.
So far we have learned how to build functions in 1D (F1D class), 2D (F2D class) and 3D (F3D class). In addition to these “fixed dimension” classes, there is a FND class which can be used to build a function with arbitrary parameters and variables. To build such function is very easy and similar to the above styles, only now one should be more explicit about the names of variables. As example, below we make a function with 4 variables, called xx, yy,bb,kk:
from jhplot import * f=FND("xx*sqrt(yy)*bb*+kk",'xx,yy,bb,kk') ans=f.eval('xx=10,yy=1,bb=0,kk=20') print ans
Such functions can be evaluated at any variable values and plotted.
Let us give a small example showing how to integrate using a trapezium rule. We will integrate this function between 1 and 10 using 10k iterations.
from jhplot import F1D f1=F1D('cos(x)^3') print f1.integral(10000,1,10)
More examples are given in the section Integration
Please read the section Function minimization
Multidimensional functions can also be built using the package jhplot.math.exp4j.
In the example below we build a function of 4 variables x,y,z,u and evaluate it:
from de.congrace.exp4j import * calc = ExpressionBuilder("f(x,y,z,u)=x * y *cos()- 2+z-u^2").build() calc.setVariable("x",1); calc.setVariable("y",20); calc.setVariable("z",1); calc.setVariable("u",20); print calc.calculate()
Same can be done in a somewhat different way:
from de.congrace.exp4j import * calc = ExpressionBuilder("x * y *cos(x)- 2+z-u^2") calc.withVariableNames("x","y","z","u") calc=calc.build() calc.setVariable("x",1); calc.setVariable("y",20); calc.setVariable("z",1); calc.setVariable("u",20); print calc.claculate()
You can evaluate function for arrays or even make X-Y array to draw the function. For example, let us evaluate this function for an array:
The output will be shown as :
array('d', [-384.1705803038421, -364.6281029269727, -392.532799516408, -461.54419962463425, -496.89242746631385, -434.5298597838711, -309.02187617936954, -326.81867265648384])
Next, let us draw this function as symbols with some step.
from jhplot import * from de.congrace.exp4j import * c1 = HPlot("Canvas",600,400) c1.setGTitle("Title"); c1.visible(1) c1.setAutoRange() calc = ExpressionBuilder("x * y*sin(x) - 2+z-u^2") calc.withVariableNames("x","y","z","u") calc=calc.build() calc.setVariable("x",1) calc.setVariable("y",20) calc.setVariable("z",1) calc.setVariable("u",20) p1=calc.calculate("x",10,20,50) c1.draw(p1)
This will draw the function as symbols:
You can build an arbitrary function using Python and plot it, mixing Java and Jython libraries in one code. You can put an arbitrary complex expressions and “if” statements. In the example below we make a custom function using a Jython class and build an “ExpressionBuilder” object. then we evaluate this function for array of “X” values and plot it.
Using special functions
You can integrate special functions from third-party Java libraries into your code and show them in 2D and 3D.
Please read the section Parametric functions.
Information for advanced users
click here if you want to know more
click here if you want to know more
— Sergei Chekanov 2010/03/07 16:37