DMelt:Math/3 Non Parametric Functions
Non-parametric functions
The most flexible way to draw functions is to use codding with objects and calling third-party Java libraries directly, instead of defining a function using strings as it was done for jhplot.F1D or jhplot.F2D classes. Here we will show how to create functions completely programmically using any arbitrary definition. Below we will show several approaches.
Extending FNon Java class
Let us consider a function of the form:
if x>3: y=x*x*sqrt(x) if x<3: y=0
To construct the mathematical functions defined above and plot it, one can build a new class by extending the class jhplot.FNon. You will need to overwrite the method "value()" that returns the calculated value.
This example shows how to do this assuming no free parameters:
from java.lang import Math from jhplot import * class MyFunc(FNon): def value(self, x): y=x[0]*x[0]*Math.sqrt(x[0]) if (x[0]<3): y=0 return y c1 = HPlot() # plot data and the fit function c1.visible(); c1.setAutoRange() pl = MyFunc("Title",1,0) # assume 1 variable, 0 parameters f1=F1D(pl,0,10) # convert to plottable function (0-10) c1.draw(f1)
Here we used functions from the Java class java.lang.Math with mathematical functions. Note that x[0] indicates a variable (0 means that the dimension of this function is one). As you can see, we define the function using Python codding, and then use it as input for the class jhplot.F1D that can be plotted. The result of this script is shown below.
You can extend this example by adding two free parameters, p[0] and p[1]. This example shows how to do this:
from java.lang import Math from jhplot import * class MyFunc(FNon): def value(self, x): y=x[0]*x[0]*Math.sqrt(x[0])*self.p[0]+self.p[1] if (x[0]<4): y=0 return y c1 = HPlot() # plot data and the fit function c1.visible() c1.setAutoRange() pl = MyFunc("test",1,2) print "f(2)= ",pl.value([2]) print pl.numberOfParameters() print pl.dimension() print pl.parameterNames().tolist() pl.setParameter("par0",100) pl.setParameter("par1",20) print pl.parameters() f1=F1D(pl,0,10) # convert to plottable function c1.draw(f1)
with the image is
Note that you can also construct functions in a similar way using Java codding.
Using user-defined steps
Here is an example of some complex function of the form:
if x>3: exp(sqrt(x))+log10(x*exp(x)) if x<3: 1
This time we will draw this function using Java methods from the class java.lang.Math:
from jhplot import * from java.lang.Math import * def func(min,max): f=P1D("exp(sqrt(x))+log10(x*exp(x))") step=(max-min)/100.0 # define step for i in range(100): x=min+step*i y=exp(sqrt(x))+log10(x*exp(x)) # get value of function if (x<3): y=1 f.add(x,y) return f c1 = HPlot() # plot c1.visible(); c1.setAutoRange() p=func(1,10) # plot between 1 and 100 p.setStyle('l') p.setPenWidth(3) c1.draw(p)
As you see, it takes more codding to create such function, but the function can be as complex as you want. In this example we used the class jhplot.P1D which keeps X-Y values and used 100 steps for evaluation. Note that you can call various special functions in this example if you will import appropriate Java class.
The result of this script is:
Using Java coding
Since all classes are implemented in Java, one can use the standard Java syntax to draw functions:
import jhplot.*; class plot { public static void main(String[] args) { F1D f1 = new F1D("2*exp(-x*x/50)+sin(pi*x)/x", -2.0, 5.0); HPlot c1 = new HPlot("Canvas"); c1.visible(); c1.setAutoRange(); c1.draw(f1); } }
Using Python definition
So far we have considered functions that can be contracted using Jython, as well as Java, and any other Java scripting language. The reason is that we used only Java classes. Next we will consider an approach that can be used using Python-only approach.
Let us illustrate this approach here. We will plot the function:
if x>0 y=a*x^{2}+b
x=0 y=0
if x< 0 y=a*x*cos(x)*b
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:
from jhplot import * from java.awt import Color c1=HPlotXYZ("test",600,400,2,1); c1.visible() h1=P2D() h1.add(10,10,20) h1.add(20,20,50) h1.add(15,12,7) c1.add(h1,10,Color.red) c1.setAxisPenWidth(1) c1.animate() c1.update() c1.cd(2,1) f1=F2D("x*x+y*y",-1,1,-1,1) c1.setAxisPenWidth(3) c1.setTickDecimalAll(1) c1.add(f1) c1.update()
The output is:
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.
A second approach to show functions is discussed in the section Distribution Function where we fill function using a third-party class. You can find more example how to create mathematical functions in 3D programmically in later sections.