In104 Scienti c Programming in

advertisement
In104
Scientic Programming in Java
The creation of software involves four basic
activities:
1. establishing the requirements and tasks,
2. creating a design and a data structure,
3. implementing the code,
4. testing the implementation.
The activities overlap and interact, often forming a repetitive development process.
1
In104
Scientic Programming in Java
Example; Solving a nonlinear algebraic equation
f (x ) = 0
using the Secant method.
6f
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
-x
x x
x
s
s
2
1
0
f (x)
A sequence of approximations:
xk+1
= xk
f (xk )
xk
f (xk )
2
x0; x1; x2; : : :
xk 1
:
f (xk 1 )
In104
Scientic Programming in Java
Requirements:
Given a nonlinear function
Given two initial guesses:
Given a tolerance
>
0.
Task:
Compute the root x.
3
f
x0
= f (x);
and
x1 ;
In104
Scientic Programming in Java
Design:
Dene f (x) as a method:
double fFunc (double x)
Input two numbers:
x0
and
x1;
Implement the algorithm as a method:
while jf (xk )j > do
xk
xk+1 = xk
f (xk )
f (xk )
k =k+1
end
Report result.
4
xk 1
f (xk 1)
In104
Scientic Programming in Java
Class SimpleSecant:
public class SimpleSecant {
protected double xkp, xk, xkm;
protected double fxk, fxkm;
protected boolean converged;
protected final double epsilon = 1.0e-6;
public static void main (String[] args)
{
SimpleSecant solver = new SimpleSecant();
solver.inputInitGuess (args);
solver.iterate ();
solver.report ();
}
protected void inputInitGuess (String[] args)
{
if (args.length!=2) {
System.out.println ("You must give 2 numbers on command-line!");
Runtime.getRuntime().exit (-1);
}
}
try {
xkm = Double.valueOf(args[0]).doubleValue();
xk = Double.valueOf(args[1]).doubleValue();
}
catch (NumberFormatException exception) {
System.out.println ("Format of the number(s) is incorrect!");
Runtime.getRuntime().exit (-1);
}
5
In104
Scientic Programming in Java
protected void iterate ()
{
fxk = fFunc(xk);
fxkm = fFunc(xkm);
converged = false;
}
while (!converged) {
xkp = xk-fxk*(xk-xkm)/(fxk-fxkm);
fxkm = fxk;
fxk = fFunc(xkp);
if (Math.abs(fxk)<=epsilon)
converged = true;
xkm = xk;
xk = xkp;
}
protected void report ()
{
if (!converged) {
System.out.println ("The method didn't converge!");
}
else {
System.out.println ("Found x="+xkp+" f(x)="+fxk);
}
}
protected double fFunc (double x)
{
return x*Math.sin(x);
}
} // end of class SimpleSecant
6
In104
Scientic Programming in Java
Improvement of the robustness:
1. Introduce an upper bound on maximum
number of iterations;
2. Stop iterations if
f
(xk )
f (xk 1 ) < 2 :
protected void iterate ()
{
fxk = fFunc(xk);
fxkm = fFunc(xkm);
converged = false;
k = 0;
}
while (!converged && ++k<=max_iterations) {
if (Math.abs(fxk-fxkm)<epsilon2) {
k = max_iterations;
}
else {
xkp = xk-fxk*(xk-xkm)/(fxk-fxkm);
fxkm = fxk;
fxk = fFunc(xkp);
if (Math.abs(fxk)<=epsilon)
converged = true;
xkm = xk;
xk = xkp;
}
}
7
In104
Scientic Programming in Java
User-developed library:
Organization of self-developed functionalities
for reuse.
A Java package is a collection of classes and
their associated methods.
The classes in a package may or may not be
related by inheritance.
A package is used to group similar and interdependent classes together.
8
In104
Scientic Programming in Java
The in104.jar library has 4 packages:
ifi.math.function
ifi.math.linalg
ifi.math.spline
ifi.plot
Documentation:
http://www.ifi.uio.no/~in104/in104.jar.doc/packages.html
Usage:
1. Extend environment variable CLASSPATH in
the .envir le
setenv CLASSPATH /hom/in104/www_docs/jars/in104.jar\:$CLASSPATH
2. Use e.g. import ifi.plot.* in program.
9
In104
Scientic Programming in Java
The ifi.math.linalg package:
Class LinEqSolve is the only member class of
the package. It has functionalities for solving
systems of linear equations.
The solution of Ax = b is accomplished in two
steps:
1. LinEqSolve.factLU (int dim, double[][] A)
LU-factorization of the matrix A;
(The content of A is actually modied by the
LU factorization.)
2. LinEqSolve.forwBackLU (int dim, double[][]
A, double[] b, double[] x)
Given the factorized matrix A and the righthand side vector b, this method computes the
solution x.
10
In104
Scientic Programming in Java
One example of using class LinEqSolve:
import ifi.math.linalg.*;
class TestLinEqSolve
{
public static void main (String[] args) {
double A[][] = new double[3][3];
A[0][0]=2; A[0][1]=2; A[0][2]=3;
A[1][0]=1; A[1][1]=4; A[1][2]=5;
A[2][0]=1; A[2][1]=3; A[2][2]=1;
double b[] = new double[3];
b[0] = 15; b[1] = 24; b[2] = 10;
double x[] = new double[3];
LinEqSolve.factLU (3,A);
LinEqSolve.forwBackLU (3,A,b,x);
System.out.println ("solution is "+x[0]+" "+x[1]+" "+x[2]);
}
}
11
In104
Scientic Programming in Java
Use of polynomials of order d in the least squares
method
Problem: Given a set of data points (xk ; yk )nk=1,
P
try to nd a polynomial p(x) = dj=0 cj xj such
that
n
X
is minimized.
k=1
(p(xk )
12
yk )
2
In104
Scientic Programming in Java
Equivalently,
c = (c0; c1; : : : ; cd)T
can be determined by solving Ac = b, where
n
A = aij ; aij = xik+j
X
k=1
and
b
= (b0; b1; : : : ; bd)T ;
for 0 i; j d.
13
bi
=
n
X
k=1
yk xik ;
In104
Scientic Programming in Java
A Java applet:
Fixed data set (xk ; yk );
Arbitrary choice of polynomial order d;
d
=1
14
In104
Scientic Programming in Java
d
=4
15
In104
Scientic Programming in Java
Curve plotting:
We want to a draw a curve
(x1; y1); (x2; y2); (x3; y3); : : :
onto a Java Graphics object.
Coordinate transformation: (x; y)
ymax 6
......................................
.........
......
......
....
......
....
.
.
.
.
....
...
.
.
.
...
..
.
.
...
.
..
.
...
.
.
..
...
.
.
.
...
..
.
.
...
..
.
.
...
..
.
.
...
..
.
.
...
..
.
.
...
...
.
...
..
.
...
..
.
...
..
...
.
.
.
...
.
..
...
.
.
.
..
.
.
...
.
.
.
...
.
.
...
..
.
...
..
.
.
...
.
.
...
.
.
.
...
.
.
.
...
.
.
.
...
..
.
...
..
.
...
.
.
.
...
.
.
.
...
.
.
.
.
.
.
..
.
..
.
.
...
...
...
.
..
...
..
...
.
.
..
...
..
...
.
.
...
ymin
xmin
y^min
(^x; y^).
-
........................................
.........
......
......
....
......
....
.
.
.
....
....
...
....
.
.
.
...
..
.
.
...
.
...
.
...
.
..
...
.
.
..
...
.
.
..
...
.
.
..
...
.
.
..
...
.
.
...
...
.
...
..
.
...
..
.
...
.
.
.
...
.
.
.
...
..
.
...
..
.
...
.
.
.
...
..
.
...
..
.
...
..
...
.
.
.
...
.
.
.
...
.
..
...
.
.
...
.
.
...
..
.
...
..
.
.
...
.
.
.
...
.
.
.
..
.
.
.
.
.
..
.
..
.
.
...
...
...
.
..
...
..
...
.
.
..
...
..
...
.
.
...
- y^max ?
xmax
x^min
16
!
x^max
In104
Scientic Programming in Java
The coordinate transformation is achieved by
a scaling (sx; sy ) and a translation (tx; ty ), i.e.,
x
^
=
y
^ =
where
8
<
:
sx
sy
and
8
<
:
tx
ty
= x^min
= y^max
=
=
sx x + tx ;
sy y
+ ty ;
x^max
xmax
y^max
ymax
xminsx
yminsy
x^min
xmin
y^min
ymin
= x^min xmin xx^max
max
y
^max
= y^max + ymin ymax
17
x^min
xmin
y^min
ymin
In104
Scientic Programming in Java
Class MultipleLS:
import
import
import
import
java.applet.*;
java.awt.*;
java.awt.event.*;
ifi.math.linalg.*;
public class MultipleLS extends Applet implements ItemListener
{
/* the original data points */
final private int num_pts = 10;
private double[] x = { 1,2,3,4,5,6,7,8,9,10 };
private double[] y = { 398, 396, 399, 413, 411,
411, 413, 416, 411, 412 };
final private double x_min = 1, x_max = 10;
final private double y_min = 396, y_max = 416;
private double[] x_hat, y_hat; // Java coordinates
/* points used to plot the LS-approximation curve */
private int num_plot_pts;
private double[] x_coords, y_coords;
// Java coordinates
private double x_hat_min, x_hat_max, y_hat_min, y_hat_max;
private int polynom_order;
Choice order_choice;
18
In104
Scientic Programming in Java
public void init ()
{
/* allocate storage for the curve of approximation */
num_plot_pts = this.getBounds().width-10;
x_coords = new double[num_plot_pts];
y_coords = new double[num_plot_pts];
int i;
for (i=0; i<num_plot_pts; i++)
x_coords[i] = i+5; // these coordinates are fixed
/* the plot region on the Applet */
x_hat_min = 5; x_hat_max = num_plot_pts+4;
y_hat_min = 40; y_hat_max = this.getBounds().height-20;
/* find the Java coordinates of the data points */
x_hat = new double[num_pts]; y_hat = new double[num_pts];
for (i=0; i<num_pts; i++) {
x_hat[i] = x[i]; y_hat[i] = y[i];
}
transformX (x_hat); transformY (y_hat);
order_choice = new Choice();
order_choice.addItemListener(this);
order_choice.add("polynom order 0");
order_choice.add("polynom order 1");
order_choice.add("polynom order 2");
order_choice.add("polynom order 3");
order_choice.add("polynom order 4");
order_choice.add("polynom order 5");
order_choice.add("polynom order 6");
add (order_choice);
polynom_order = 0;
leastSquareApproximation ();
}
paint (this.getGraphics());
19
In104
Scientic Programming in Java
public void paint (Graphics g)
{
g.setColor(getBackground());
g.clearRect (0,0,getBounds().width-1,getBounds().height-1);
int i;
/* plot the original data points */
g.setColor (Color.red);
for (i=0; i<num_pts; i++)
g.drawOval ((int)(x_hat[i]-1),(int)(y_hat[i]-1),3,3);
}
/* plot the LS-approximation as a curve */
g.setColor (Color.blue);
for (i=0; i<num_plot_pts-1; i++)
g.drawLine ((int) x_coords[i], (int) y_coords[i],
(int) x_coords[i+1], (int) y_coords[i+1]);
20
In104
Scientic Programming in Java
public void itemStateChanged(ItemEvent e)
{
ItemSelectable curr = e.getItemSelectable();
if (curr==order_choice) {
polynom_order = order_choice.getSelectedIndex();
leastSquareApproximation ();
repaint ();
}
}
private void transformX (double[] xv)
{
final double sx = (x_hat_max-x_hat_min)/(x_max-x_min);
final double tx = x_hat_min-x_min*sx;
}
int i;
for (i=0; i<xv.length; i++)
xv[i] = sx*xv[i]+tx;
private void transformY (double[] yv)
{
final double sy = -(y_hat_max-y_hat_min)/(y_max-y_min);
final double ty = y_hat_max-y_min*sy; /* sy is negative */
}
int i;
for (i=0; i<yv.length; i++)
yv[i] = sy*yv[i]+ty;
21
In104
Scientic Programming in Java
private void leastSquareApproximation ()
{
double[][] A = new double[polynom_order+1][polynom_order+1];
double[] rhs = new double[polynom_order+1];
double[] coef = new double[polynom_order+1];
int i,j,k;
double pow_order;
/* build matrix A and right-hand side vector rhs */
for (i=0; i<=polynom_order; i++) {
for (j=i; j<=polynom_order; j++) {
A[i][j] = 0.;
pow_order = (double)(i+j);
for (k=0; k<num_pts; k++)
A[i][j] += Math.pow(x[k],pow_order);
}
rhs[i] = 0.;
pow_order = (double) i;
for (k=0; k<num_pts; k++)
rhs[i] += y[k]*Math.pow(x[k],pow_order);
}
/* matrix A is symmetric */
for (i=1; i<=polynom_order; i++)
for (j=0; j<i; j++)
A[i][j] = A[j][i];
/* solve the linear system */
LinEqSolve.factLU (polynom_order+1, A);
LinEqSolve.forwBackLU (polynom_order+1, A, rhs, coef);
22
In104
Scientic Programming in Java
double x_pos, dx;
dx = (x_max-x_min)/(num_plot_pts);
x_pos = x_min;
for (i=0; i<num_plot_pts; i++) {
y_coords[i] = 0.;
for (j=0; j<=polynom_order; j++) {
y_coords[i] += coef[j]*Math.pow(x_pos,j);
}
x_pos += dx;
}
}
transformY (y_coords);
23
Download