001package algs12; 002import stdlib.*; 003/* *********************************************************************** 004 * Compilation: javac Vector.java 005 * Execution: java Vector 006 * 007 * Implementation of a vector of real numbers. 008 * 009 * This class is implemented to be immutable: once the client program 010 * initialize a Vector, it cannot change any of its fields 011 * (N or data[i]) either directly or indirectly. Immutability is a 012 * very desirable feature of a data type. 013 * 014 * % java Vector 015 * x = [ 1.0 2.0 3.0 4.0 ] 016 * y = [ 5.0 2.0 4.0 1.0 ] 017 * z = [ 6.0 4.0 7.0 5.0 ] 018 * 10z = [ 60.0 40.0 70.0 50.0 ] 019 * |x| = 5.477225575051661 020 * <x, y> = 25.0 021 * 022 * 023 * Note that Vector is also the name of an unrelated Java library class. 024 * 025 *************************************************************************/ 026 027public class Vector { 028 029 private final int N; // length of the vector 030 private final double[] data; // array of vector's components 031 032 033 // create the zero vector of length n 034 public Vector(int n) { 035 N = n; 036 data = new double[N]; 037 } 038 039 // create a vector from either an array or a vararg list 040 // this constructor uses Java's vararg syntax to support 041 // a constructor that takes a variable number of arguments, such as 042 // Vector x = new Vector(1.0, 2.0, 3.0, 4.0); 043 // Vector y = new Vector(5.0, 2.0, 4.0, 1.0); 044 public Vector(double... d) { 045 N = d.length; 046 047 // defensive copy so that client can't alter our copy of data[] 048 data = new double[N]; 049 for (int i = 0; i < N; i++) 050 data[i] = d[i]; 051 } 052 // return the length of the vector 053 public int length() { 054 return N; 055 } 056 057 // return the inner product of this Vector a and b 058 public double dot(Vector that) { 059 if (this.N != that.N) throw new Error("Dimensions don't agree"); 060 double sum = 0.0; 061 for (int i = 0; i < N; i++) 062 sum = sum + (this.data[i] * that.data[i]); 063 return sum; 064 } 065 066 // return the Euclidean norm of this Vector 067 public double magnitude() { 068 return Math.sqrt(this.dot(this)); 069 } 070 071 // return the Euclidean distance between this and that 072 public double distanceTo(Vector that) { 073 if (this.N != that.N) throw new Error("Dimensions don't agree"); 074 return this.minus(that).magnitude(); 075 } 076 077 // return this + that 078 public Vector plus(Vector that) { 079 if (this.N != that.N) throw new Error("Dimensions don't agree"); 080 Vector c = new Vector(N); 081 for (int i = 0; i < N; i++) 082 c.data[i] = this.data[i] + that.data[i]; 083 return c; 084 } 085 086 // return this + that 087 public Vector minus(Vector that) { 088 if (this.N != that.N) throw new Error("Dimensions don't agree"); 089 Vector c = new Vector(N); 090 for (int i = 0; i < N; i++) 091 c.data[i] = this.data[i] - that.data[i]; 092 return c; 093 } 094 095 // return the corresponding coordinate 096 public double cartesian(int i) { 097 return data[i]; 098 } 099 100 // create and return a new object whose value is (this * factor) 101 public Vector times(double factor) { 102 Vector c = new Vector(N); 103 for (int i = 0; i < N; i++) 104 c.data[i] = factor * data[i]; 105 return c; 106 } 107 108 109 // return the corresponding unit vector 110 public Vector direction() { 111 if (this.magnitude() == 0.0) throw new Error("Zero-vector has no direction"); 112 return this.times(1.0 / this.magnitude()); 113 } 114 115 116 // return a string representation of the vector 117 public String toString() { 118 String s = ""; 119 for (int i = 0; i < N; i++) 120 s = s + data[i] + " "; 121 return s; 122 } 123 124 125 126 127 // test client 128 public static void main(String[] args) { 129 double[] xdata = { 1.0, 2.0, 3.0, 4.0 }; 130 double[] ydata = { 5.0, 2.0, 4.0, 1.0 }; 131 Vector x = new Vector(xdata); 132 Vector y = new Vector(ydata); 133 134 StdOut.println(" x = " + x); 135 StdOut.println(" y = " + y); 136 137 Vector z = x.plus(y); 138 StdOut.println(" z = " + z); 139 140 z = z.times(10.0); 141 StdOut.println(" 10z = " + z); 142 143 StdOut.println(" |x| = " + x.magnitude()); 144 StdOut.println(" <x, y> = " + x.dot(y)); 145 StdOut.println("dist(x, y) = " + x.distanceTo(y)); 146 StdOut.println("dir(x) = " + x.direction()); 147 148 } 149}