-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathVector.h
179 lines (161 loc) · 5.36 KB
/
Vector.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#ifndef CH1_VECTOR_H
#define CH1_VECTOR_H
#include <vector>
#include <iostream>
#include <ostream>
#include <sstream>
#include <cmath>
#include <stdexcept>
using std::vector;
using std::runtime_error;
using std::ostream;
using std::ostringstream;
/**
* The {@code Vector} class represents a <em>d</em>-dimensional Euclidean vector.
* Vectors are immutable: their values cannot be changed after they are created.
* It includes methods for addition, subtraction,
* dot product, scalar product, unit vector, Euclidean norm, and the Euclidean
* distance between two vectors.
* <p>
* For additional documentation,
* see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
class Vector {
public:
/**
* Initializes a d-dimensional zero vector.
*
* @param d the dimension of the vector
*/
Vector(int d) : d(d), data(d, 0) {}
/**
* Initializes a vector from either an array or a vararg list.
* The vararg syntax supports a constructor that takes a variable number of
* arugments such as Vector x = new Vector(1.0, 2.0, 3.0, 4.0).
*
* (Note: this version use vector rather than vararg list)
* @param a the array or vararg list
*/
Vector(vector<double> arr) : d(arr.size()), data(arr) {}
/**
* Returns the dimension of this vector.
*
* @return the dimension of this vector
*/
int dimension() const noexcept { return d; }
/**
* Returns the do product of this vector with the specified vector.
*
* @param that the other vector
* @return the dot product of this vector and that vector
* @throws IllegalArgumentException if the dimensions of the two vectors are not equal
*/
double dot(const Vector &that) {
if (d != that.d) throw runtime_error("Dimension don't agree");
double sum = 0.0;
for (int i = 0; i < d; ++i)
sum += (data[i] * that.data[i]);
return sum;
}
/**
* Returns the magnitude of this vector.
* This is also known as the L2 norm or the Euclidean norm.
*
* @return the magnitude of this vector
*/
double magnitude() {
return sqrt(dot(*this));
}
/**
* Returns the Euclidean distance between this vector and the specified vector.
*
* @param that the other vector
* @return the Euclidean distance between this vector and that vector
* @throws IllegalArgumentException if the dimensions of the two vectors are not equal
*/
double distanceTo(const Vector &that) {
if (d != that.d) throw runtime_error("Dimensions don't agree");
return minus(that).magnitude();
}
/**
* Returns the sum of this vector and the specified vector.
*
* @param that the vector to add to this vector
* @return the vector whose value is {@code (this + that)}
* @throws IllegalArgumentException if the dimensions of the two vectors are not equal
*/
Vector plus(const Vector &that) {
if (d != that.d) throw runtime_error("Dimensions don't agree");
Vector c(d);
for (int i = 0; i < d; i++)
c.data[i] = data[i] + that.data[i];
return c;
}
/**
* Returns the difference between this vector and the specified vector.
*
* @param that the vector to subtract from this vector
* @return the vector whose value is {@code (this - that)}
* @throws IllegalArgumentException if the dimensions of the two vectors are not equal
*/
Vector minus(const Vector &that) {
if (d != that.d) throw runtime_error("Dimensions don't agree");
Vector c(d);
for (int i = 0; i < d; i++)
c.data[i] = data[i] - that.data[i];
return c;
}
/**
* Returns the ith cartesian coordinate.
*
* @param i the coordinate index
* @return the ith cartesian coordinate
*/
double cartesian(int i) const noexcept {
return data[i];
}
/**
* Returns the scalar-vector product of this vector and the specified scalar
*
* @param alpha the scalar
* @return the vector whose value is {@code (alpha * this)}
*/
Vector scale(double alpha) {
Vector c(d);
for (int i = 0; i < d; i++)
c.data[i] = alpha * data[i];
return c;
}
/**
* Returns a unit vector in the direction of this vector.
*
* @return a unit vector in the direction of this vector
* @throws ArithmeticException if this vector is the zero vector
*/
Vector direction() {
if (magnitude() == 0.0) throw runtime_error("Zero-vector has no direction");
return scale(1.0 / magnitude());
}
/**
* Returns a string representation of this vector.
*
* @return a string representation of this vector, which consists of the
* the vector entries, separates by single spaces
*/
friend ostream &operator<<(ostream &stream, const Vector &v);
private:
int d; // dimension of the vector
vector<double> data; // array of vector's components
};
ostream &operator<<(ostream &stream, const Vector &v) {
ostringstream out;
for (int i = 0; i < v.d; ++i)
out << v.data[i] << " ";
stream << out.str();
return stream;
}
#endif //CH1_VECTOR_H