Tutorial:DataMelt/2 Mathematical Functions
1D functions
Functions with one variable
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:
[math]\displaystyle{
f(x)=2*\exp(-x*x/50)+\sin(3.14*x)
}[/math].
Such function can be constructed using the Java class jhplot.F1D (1D means one-dimensional function). After we constructed such function, we can evaluate it at any give "x" value:
<jc lang="dmelt"> from jhplot import F1D f = F1D("2*exp(-x*x/50)+sin(pi*x)/x") print f.eval(10) # evaluate at x=10 </jc>
One can also evaluate this function at several different x values:
<jc lang="dmelt"> from jhplot import F1D f = F1D("2*exp(-x*x/50)+sin(pi*x)/x") print f.eval([1,2,3,4]) # evaluate at x=11,2,3,4 </jc>
To draw the function, one should specify limits during the
function initialization (or later using the
methods of the Java object jhplot.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:
<jc lang="dmelt"> from jhplot import F1D, HPlot f = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0) c = HPlot("Canvas") c.visible() c.setAutoRange() c.draw(f) </jc>
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
[math]\displaystyle{ \cos(x*x)+\sin(1/x)*x^2) }[/math].
This code integrates the function using different methods, in x 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:
<jc lang="dmelt"> from jhplot import F1D import time f1=F1D('cos(x*x)+sin(1.0/x)*x^2') methods=['trapezium','gauss4', 'gauss8', 'richardson', 'simpson'] for m in methods:
start = time.clock() d=f1.integral(m,5000,10,100) t = time.clock()-start print m,' =',d,' time (ms)=',t*1000
</jc>
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
Functions:
String | Definition |
---|---|
abs | absolute value |
log(x) | Natural Logarithm |
sqrt(x) | squared root |
exp(x) | Exp |
ceil | nearest upper integer |
floor | nearest lower integer |
cbrt | cubic root |
sin(x) | Sine |
cos(x) | Cosine |
tan(x) | Tangent |
asin(x) | ArcSine |
acos(x) | ArcCosine |
atan(x) | ArcTangent |
sinh(x) | Hyperbolic Sine |
cosh(x) | Hyperbolic Cosine |
tanh(x) | Hyperbolic Tangent |
One can also use some predefined constants, such as pi or Pi (the pi value, 3.14..)
Let us give the examples:
<jc lang="dmelt"> from jhplot import F1D 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+x2-x3") # correct answer -1 print f1.eval(2) </jc>
Displaying several functions
Here is a more detailed example showing how to plot several functions using different colors:
<jc lang="dmelt_edit"> from java.awt import Color from jhplot import F1D,HPlot
f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0) f1.setPenDash(4); f1.setPenWidth(2)
f2 = F1D("exp(-x*x/30)", -2.0, 5.0) f2.setColor(Color.green); f2.setPenWidth(3)
c1 = HPlot("Canvas") c1.setGTitle("2 functions", Color.red) c1.setNameX("X"); c1.setNameY("Y values") c1.visible() c1.setAutoRange() c1.draw(f1); c1.draw(f2) </jc>
![]() | Exercise: add a third function [math]\displaystyle{ \cos(x)*x }[/math] and show it with the red color. |
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 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.
<jc lang="dmelt"> from java.awt import Color from jhplot import HPlot,F1D
c1 = HPlot("Canvas") c1.visible() c1.setAutoRange() c1.setNameX("X"); c1.setNameY("Y")
f1 = F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0); c1.draw(f1)
h=f1.getH1D("Histogram",500,1,5) # histogram with 500 bins between 1 and 5 h.setColor(Color.red) h.setFill(1); h.setFillColor(Color.red) c1.draw(h) </jc>
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.
2D functions
Functions in 2 dimensions can be build analogously using the
Java class jhplot.F2D.
The example below shows how to construct and evaluate a function 2D:
<jc lang="dmelt"> from jhplot import F2D f = F2D("2*exp(-x*y/50)+sin(pi*x)/y") print f.eval(10,20) </jc>
To show F2D function, use the canvas HPlot3D. In this example we shows 2 functions on top of each other:
<jc lang="dmelt"> from jhplot import F2D, HPlot3D c1 = HPlot3D("Canvas") c1.visible() c1.setNameX("X"); c1.setNameY("Y") f1 = F2D("2*exp(-x*y/4)", -2.0, 5.0, -2.0, 5.0) f2 = F2D("4*x*y", -2.0, 5.0, -2.0, 5.0) c1.draw(f1,f2) </jc>
3D functions
Functions in 2 dimensions can be build by analogy using the
Java class jhplot.F3D.
The example below shows how to construct and evaluate a function 3D:
<jc lang="dmelt"> from jhplot import F3D f1 = F3D("2*exp(-x*y/50)+sin(pi*x)/z") print f1.eval(10,20,30) </jc>
FND functions
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 <jabvadoc>jhplot.F1D</javadoc> 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:
<jc lang="dmelt"> from jhplot import FND f=FND("xx*sqrt(yy)*bb*+kk",'xx,yy,bb,kk') ans=f.eval('xx=10,yy=1,bb=0,kk=20') print ans </jc> Such functions can be evaluated at any variable values and plotted.
Differentiation
Simplification
Expression Builder
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:
print calc.eval("x",[1,2,3,4,5,6,7,9])
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.
Functions using arbitrary definition
So far we have considered functions contracted using a string. One can define an arbitrary function using Jython syntax and call any Python or Java library inside such definition. We will illustrate this approach in this example: Let us consider a function which looks as:
[math]\displaystyle{ if x\gt 0 right y=a*x^{2}+b }[/math]
[math]\displaystyle{ x=0 right y=0 }[/math]
[math]\displaystyle{ if x\lt 0 right y=a*x*\cos(x)*b }[/math]
where a and b are constants. To build such function using a single string is not easy, but it is possible to construct such function using the standard Jython. Below we will construct such function and make a plot for a=20 and b=30:
In a similar way one can build any function with several variables. Note that we create a class of this function "cmt", where v[0] denotes variable "x". For several variables, say x and y, one should use v[0] (for x) and v[1] for y. Analogously, one can use the same approach for x variable.
Parametric functions
Parametric functions can be constructed using the Java class jhplot.FPR.
The variables "u" and "v" are parametric variables used to build "x,y,z".
To display such functions, use the canvas jhplot.HPlot3DP.
<jc lang="dmelt">
from java.awt import Color
from jhplot import HPlot3DP,FPR
c1 = HPlot3DP("Canvas")
c1.setGTitle('3D surfaces')
c1.visible();
f1=FPR('u=2 Pi u; z=1.5*(v-.5); x=z cos(u)*.8-0; y=z sin(u)*.8+0')
f1.setFillColor(Color.green)
c1.draw(f1)
</jc>
One can overlay several functions on top of each other and set the transparency level. In this example we show this:
<jc lang="dmelt">
from java.awt import Color
from jhplot import FPR,HPlot3DP
c1 = HPlot3DP("Canvas",500,600) c1.setGTitle('Sphere and torus') c1.visible()
- a transparent sphere
f1=FPR('r=0.6; u=2 Pi u; v=Pi v; x=r cos(u) sin(v); y=r sin(u) sin(v); z=r cos(v)') f1.setDivisions(20,20) f1.setLineColor(Color.blue) f1.setFillColor( Color(20,170,170, 100) )
- a tour
f2=FPR('u=2 Pi u; v=2 Pi v; r=0.7+.2cos(u); z=.2 sin(u)-0.0; x=r cos(v); y=r sin(v)') f2.setDivisions(30,30) f2.setFillColor( Color(200,170,170,255) )
c1.draw(f1); c1.draw(f2) </jc>