2/11/12
1.00 Lecture 30
Matrices
Reading for next time: Numerical Recipes, pp. 37-42 (online)
[Link]
Matrices
• Matrix is 2-D array of m rows by n columns
a00 a01 a02 a03 a0n-1
a10 a11 a12 a13 a1n-1
a20 a21 a22 a23 a2n-1
am-1,0 am-1,1 am-1,2 am-1,3 am-1,n-1
– In math notation, we use index 1, m and 1, n.
– In Java, we usually use index 0, m-1 and 0, n-1
• They often represent a set of linear equations:
a00x0 + a01x1 + a02x2 + + a0,n-1xn-1 = b0
a10x0 + a11x1 + a12x2 + + a1,n-1xn-1 = b1
am-1,0x0 + am-1,1x1 + am-1,2x2 + + am-1,n-1xn-1 = bm-1
– n unknowns x are related by m equations
– Coefficients a are known, as are right hand side b
1
2/11/12
Matrices, p.2
• In this lecture we cover basic matrix
representation and manipulation
– Used most often to prepare matrices for use in solving
linear systems, which we cover in next lecture
• Java has 2-D arrays, declared as, for example
double[][] squareMatrix= new double[5][5];
– But there are no built-in methods for them
• So, its helpful to create a Matrix class:
– Create methods to add, subtract, multiply, form identity
matrix, etc.
– Used for matrices with a few hundred rows or so
• Sparse matrices are handled differently:
– Almost all large matrices (millions of rows or columns)
are extremely sparse (99%+ of entries are zeros)
– Store (i, j, value) in a list or 1-D array or other data
structure
2-D Arrays
double[][] data= new double[5][4];
data[0][0]
No of columns=
data data[0] 8.0 14.0 2.0 3.0
data[0].length
data[1] 5.1 4.2 6.6 0.8
data[2] 2.4 6.4 0.4 4.3
data[3] 3.3 3.2 5.5 6.6
data[4] 12.3 3.7 9.3 3.0
No. of rows=
[Link]
A 2-D array is:
a reference to a 1-D array of references to 1-D arrays of data.
This is how well store the matrix data in class Matrix
2
2/11/12
Matrix class, p.1
public class Matrix {
private double[][] data; // Reference to array
public Matrix(int m, int n) {
data = new double[m][n];
}
1 0 0
public void setIdentity() { 0 1 0
int nrows = [Link]; 0 0 1
int ncols = data[0].length;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
if (i == j)
data[i][j]= 1.0;
else
data[i][j]= 0.0;
} // Should check that matrix is square
Matrix class, p.2
public int getNumRows() { return [Link]; }
public int getNumCols() { return data[0].length; }
public double getElement(int i, int j) { return data[i][j]; }
public void setElement(int i, int j, double val) {
data[i][j] = val; }
public void incrElement(int i, int j, double incr) {
data[i][j] += incr; }
1 3 5 3 2 0 4 5 5
public Matrix add(Matrix b) {
0 2 6 + 0 4 3 = 0 6 9
Matrix result = null;
0 5 1 2 3 1 2 8 2
int nrows = [Link];
int ncols = data[0].length;
if (nrows== [Link] && ncols== [Link][0].length) {
result = new Matrix(nrows, ncols);
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
[Link][i][j]= data[i][j]+ [Link][i][j]; }
return result;
} // Objects of same class see each others private data
3
2/11/12
Matrix class, p.3
public Matrix mult(Matrix b) { 1 3 1 3 5 1 9 23
Matrix result = null; 0 2 . 0 2 6 = 0 4 12
0 5 0 10 30
int nrows = [Link];
int ncols = data[0].length;
if (ncols == [Link]) {
result = new Matrix(nrows, [Link][0].length);
for (int i= 0; i < nrows; i++)
for (int j=0; j < [Link][0].length; j++) {
double t = 0.0;
for (int k= 0; k < ncols; k++) {
t += data[i][k] * [Link][k][j]; }
[Link][i][j]= t; } }
return result;
}
public void print() {
for (int i= 0; i < [Link]; i++) {
for (int j= 0; j < data[0].length; j++)
[Link](data[i][j] + " ");
[Link](); }
[Link]();
}
}
MatrixTest
public class MatrixTest {
public static void main(String argv[]) {
Matrix mat1 = new Matrix(3,3);
Matrix mat2 = new Matrix(3,3);
[Link]();
[Link]();
Matrix res;
res = [Link](mat2);
[Link]("mat1:");
[Link]();
[Link]("mat2:");
[Link]();
[Link]("mat1 + mat2:" );
[Link]();
// Similar code for multiplication
// Add your exercise code here
}
}
4
2/11/12
Exercise 1
• Download Matrix and MatrixTest from Web site
• Write an instance method multScalar() to
multiply a matrix by a scalar (double) in class
Matrix
• Invoke your method from MatrixTest main()
• Hints for writing multScalar()
– Use add() as a rough guide
– Find the number of rows and columns in the matrix
– Create a new Matrix object to return as the result
– Loop through all entries (nested for loops) to
multiply by the scalar
– Return the result
• Modify MatrixTest main() method:
– Add a line to use the multScalar() method
– Add another line to print the resulting matrix, using
its print() method
Exercise 2 Introduction
• Implement graphics transforms from last Swing
lecture
• Instead of using Javas rotate() and scale()
methods, youll create matrices to represent
rotation and scaling, multiply them, and apply
them to a shape.
• With some perseverance, your matrix
manipulations will yield the same result as Javas
methods
5
2/11/12
Translation
⎡1 0 t x ⎤ ⎡ x ⎤ ⎡ x + t x ⎤
⎢0 1 t ⎥ ⎢ y ⎥ = ⎢ y + t ⎥
ty ⎢ y⎥⎢ ⎥ ⎢ y⎥
⎢⎣0 0 1 ⎥⎦ ⎢⎣ 1 ⎥⎦ ⎢⎣ 1 ⎥⎦
tx
Rotation
⎡ cos (α ) − sin ( α ) 0 ⎤ ⎡ x ⎤ ⎡ x cos (α ) − y sin (α )⎤
⎢ sin (α ) cos ( α ) 0 ⎥ ⎢ y ⎥ = ⎢ x sin ( α ) + y cos ( α )⎥
⎢ ⎥⎢ ⎥ ⎢ ⎥
⎣ 0 0 1⎦ ⎣1 ⎦ ⎣ 1 ⎦
6
2/11/12
Scaling
⎡ sx 0 0 ⎤ ⎡ x ⎤ ⎡ sx ∗ x ⎤
⎢0 sy 0⎥ ⎢ y ⎥ = ⎢ s y ∗ y ⎥
⎢ ⎥⎢ ⎥ ⎢ ⎥
⎢⎣ 0 0 1 ⎥⎦ ⎢⎣ 1 ⎥⎦ ⎢⎣ 1 ⎥⎦
Composing Transformations
• Suppose we want to scale point (x, y) by 2 and
then rotate by 90 degrees.
⎡0 −1 0 ⎤ ⎛ ⎡ 2 0 0 ⎤ ⎡ x ⎤ ⎞
⎢1 0 0 ⎥ ⎜ ⎢ 0 2 0 ⎥ ⎢ y ⎥ ⎟
⎢ ⎥⎜ ⎢ ⎥⎢ ⎥⎟
⎜
⎢⎣0 0 1 ⎥⎦ ⎝ ⎢⎣ 0 0 1 ⎥⎦ ⎢⎣ 1 ⎥⎦ ⎟⎠
rotate scale
7
2/11/12
Composing Transformations, 2
Because matrix multiplication is associative, we can
rewrite this as
⎛ ⎡0 −1 0 ⎤ ⎡ 2 0 0 ⎤ ⎞ ⎡ x ⎤
⎜⎢ ⎥ ⎢0 2 0⎥ ⎟ ⎢ y ⎥
⎜⎢ 1 0 0
⎥⎢ ⎥⎟⎢ ⎥
⎜ ⎢0 0 1 ⎥ ⎢0 0 1 ⎥ ⎟ ⎢ 1 ⎥
⎝⎣ ⎦⎣ ⎦⎠⎣ ⎦
⎡ 0 −2 0 ⎤ ⎡ x ⎤
= ⎢2 0 0⎥ ⎢ y ⎥
⎢ ⎥⎢ ⎥
⎢⎣ 0 0 1 ⎥⎦ ⎢⎣ 1 ⎥⎦
Exercise 2
• Download TransformTest, TransformPanel
– TransformPanel rotates (by 18 º) and scales (by 2) a
rectangle using Java affine transforms
– Run it to see the result. (Dont use this code for exercise.)
• Download TransformTest1, TransformPanel1
– These are skeletons for doing the rotations and scaling
through matrix multiplication yourself. You will:
– Create two matrices (rotate, scale) with your Matrix class
– Scale by 2 in the x and y directions and rotate by 18º (/
10)
• Look at the scaling and rotation matrices in previous slides
– Multiply the 2 matrices, save them in Matrix result. Order
matters in general
• Try it both ways here—its simple enough to give same result
– Pass the values as arguments to AffineTransform() as
shown in TransformPanel1 code on the next slides
– See if your AffineTransform produces the same result
8
2/11/12
Exercise 2: TransformTest
import [Link].*;
import [Link].*;
public class TransformTest {
public static void main(String args[]) {
JFrame frame = new JFrame("Rectangle transform");
[Link](JFrame.EXIT_ON_CLOSE);
[Link](500,500);
Container contentPane= [Link]();
TransformPanel panel = new TransformPanel();
[Link](panel, [Link]);
[Link](true);
}
}
Exercise 2: TransformPanel
import [Link].*;
import [Link].*;
import [Link].*; // For 2D classes
public class TransformPanel extends JPanel {
public void paintComponent(Graphics g) {
[Link](g);
Graphics2D g2= (Graphics2D) g;
Rectangle2D rect= new [Link](0, 0, 50, 100);
Replace these lines
[Link]([Link]);
AffineTransform baseXf = new AffineTransform();
// Scale by 2 in x, y directions, then rotate by 18 degrees
[Link]([Link]/10.0);
[Link](2.0, 2.0);
[Link](baseXf);
[Link](rect);
}
}
9
2/11/12
Exercise 2: TransformPanel, p.2
public class TransformPanel1 extends JPanel {
public void paintComponent(Graphics g) {
// Same initial lines: superclass, cast g2, new rectangle
[Link]([Link]);
Matrix s = new Matrix(3, 3);
// Set its elements to scale rectangle by 2
// Your code here
[Link]();
Matrix r = new Matrix(3, 3); // Rotate
double a = [Link] / 10; // 18 degree angle
// Set elements to rotate 18 degrees; use [Link]() and cos()
// Your code here
[Link]();
// Multiply r and s to get Matrix result
// Your code here
[Link]();
double m00 = [Link](0, 0);
double m01 = [Link](0, 1);
// Etc. Coefficients inserted in COLUMN order. Done for you.
AffineTransform baseXf =
new AffineTransform(m00, m10, m01, m11, m02, m12);
[Link](baseXf); // Only 6 elements vary in xform
[Link](rect); } }
Exercise 2 Desired Result
© Oracle. All rights reserved. This content is excluded from our Creative
Commons license. For more information, see [Link]
10
2/11/12
Exercise 3
• Modify TransfomPanel
– Almost the same as exercise 4, lecture 21
– Initially, rectangle is 50 by 100, at origin
– Apply the following transforms:
• Translate rectangle 50 pixels east, 200 pixels south
• Scale by factor of 1.5, but leave upper left corner of
rectangle in same position
• Rotate by 30 degrees counterclockwise around the origin
– Not around the upper left corner, as in lecture 21, which
would require translating to origin and back again
– Counterclockwise, not clockwise, to stay on the panel
– Draw the original rectangle in red
– Draw the transformed rectangle in blue
– Remember to apply transforms by premultiplying
by each one in order
Exercise 3 cont.
• Mechanics:
– Copy your exercise 2 solution into class
TransformPanel2
– Copy TransformTest into TransformTest2
• Have its main() create a TransformPanel2 object
– Do not use AffineTransform methods rotate(),
scale() or translate()
– Create r, s and t matrices and multiply them
appropriately to create a result matrix holding
the combined transform
– Use the first 6 coefficients of the result matrix
(m00, m10, etc.) in the AffineTransform
constructor, as in exercise 2
11
2/11/12
Exercise 3 output
© Oracle. All rights reserved. This content is excluded from our Creative
Commons license. For more information, see [Link]
Exercise 3 previous code
// Same imports as before: swing, awt, [Link]
public class TransformPanel extends JPanel {
public void paintComponent(Graphics g) {
[Link](g);
Graphics2D g2= (Graphics2D) g;
Rectangle2D rect= new [Link](0, 0, 50, 100);
[Link]([Link]);
[Link](rect);
[Link]([Link]);
AffineTransform baseXf = new AffineTransform();
[Link](-[Link]/6.0); // 3. Rotate 30° at origin
[Link](50,200); // 2. Move 50, 200 pixels
[Link](1.5, 1.5); // 1. Do scaling at origin
[Link](baseXf);
[Link](rect);
}
} // Rotation (step 3) different than earlier exercise:
// Rotate counterclockwise, not clockwise, around origin
12
MIT OpenCourseWare
[Link]
1.00 / 1.001 / 1.002 Introduction to Computers and Engineering Problem Solving
Spring 2012
For information about citing these materials or our Terms of Use, visit: [Link]