DMelt:Math/3 Non Parametric Functions

From HandWiki
Revision as of 21:46, 5 March 2024 by MainEditor (talk | contribs) (→‎Using Java coding)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Member


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 jhplot.F1D or jhplot.F2D 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 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 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 jhplot.F1D that can be plotted. The result of this script is shown below.

DMelt example: Defining and plotting a non-parametric function

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

DMelt example: Defining a non-parametric function with 2 variables

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 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 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:

DMelt example: Complex function defined programically

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:

DMelt example: Create 3D animated canvases with function + data

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.