Implementation and Application of Vector Calculations in C++

In numerical computation and scientific programming, vectors are one of the most fundamental data structures. Whether in linear algebra, computational geometry, or machine learning and engineering modeling, vector operations always play a core role. This article implements several classic vector operations based on C++ template classes and demonstrates their results through examples.1. Vector Addition and SubtractionVector addition and subtraction are the most basic operations, requiring the operands to have the same dimensions, with the operation rules being to add or subtract corresponding components one by one:

2. Scalar Multiplication (Multiplying a Scalar with a Vector) Scalar multiplication is one of the basic operations in vector space. For a scalar and a vector:

3. Dot Product (Inner Product)The dot product of vectors is defined as:

The dot product is closely related to the cosine of the angle between the vectors and is an important tool for determining the orthogonality of vectors.4. Cross Product (Outer Product)The cross product is only defined for three-dimensional vectors, and the result is still a three-dimensional vector:

The geometric meaning is to construct a vector that is perpendicular to the two vectors, with a magnitude equal to the area of the parallelogram formed by them.5. Vector NormThe norm is a measure of the length or magnitude of a vector. Common definitions are as follows:1-norm (Manhattan norm)

2-norm (Euclidean norm)

Infinity norm ( norm)

Norm

6. Unit Vector and Opposite VectorUnit Vector: Direction remains unchanged, normalizing the vector to a length of 1:

Opposite Vector: Direction is opposite, with the same magnitude:

7. Code

#include <iostream>
#include <initializer_list> // Supports initialization list {a, b, c}
using namespace std;

// Vector
enum Orientation { ROW, COL }; // Vector direction: row vector / column vector
template <typename T>
class Vector
{
private:
 T* data; // Stores vector elements
 int size; // Vector length
 Orientation orientation; // Row vector or column vector
public:
 // Normal constructor: given length n and direction, create an empty vector
 Vector(int n, Orientation orient = ROW) : size(n), orientation(orient)
 {
  data = new T[size];
for (int i = 0; i < size; i++)
   data[i] = T{};
 }
 // Initializer list constructor: allows writing Vector<int> v = {1, 2, 3}; can specify ROW or COL
 Vector(initializer_list<T> values, Orientation orient = ROW) : size(values.size()), orientation(orient)
 {
  data = new T[size];
  int i = 0;
for (auto& v : values)
   data[i++] = v;
 }
 // Copy constructor (deep copy): solves dangling pointer issues caused by return values/assignments
 Vector(const Vector& other) : size(other.size), orientation(other.orientation)
 {
  data = new T[size];
for (int i = 0; i < size; i++)
   data[i] = other.data[i];
 }
 // Move constructor (low overhead): steals resources from other
 Vector(Vector&& other) noexcept : data(other.data), size(other.size), orientation(other.orientation)
 {
  other.data = nullptr;
  other.size = 0;
 }
 // Copy assignment (deep copy, exception safe)
 Vector& operator = (const Vector& other)
 {
if (this == &other)
   return *this;
  T* newData = new T[other.size];
for (int i = 0; i < other.size; i++)
   newData[i] = other.data[i];
  delete[] data;
  data = newData;
  size = other.size;
  orientation = other.orientation;
return *this;
 }
 // Move assignment
 Vector& operator = (Vector&& other) noexcept
 {
if (this != &other)
  {
   delete[] data;
   data = other.data;
   size = other.size;
   orientation = other.orientation;
   other.data = nullptr;
   other.size = 0;
  }
return *this;
 }
 // Destructor: releases heap content
 ~Vector()
 {
  delete[] data;
 }
 // Subscript operator: v[i] accesses the i-th element
 T& operator[](int index)
 {
return data[index];
 }
 const T& operator[] (int index) const
 {
return data[index];
 }
 // Get vector length
 int getSize() const
 {
return size;
 }
 // Output vector
 void print() const
 {
  // cout << "Vector" << endl;
if (orientation == ROW) // Row vector, display in one line
  {
   cout << "[";
   for (int i = 0; i < size; i++)
    cout << data[i] << " ";
   cout << "]" << endl;
  }
else // Column vector, each element on a separate line
  {
   for (int i = 0; i < size; i++)
    cout << "[" << data[i] << "]" << endl;
  }
 }
 // Vector addition
 Vector operator+ (const Vector& other) const
 {
if (size != other.size)
   throw std::invalid_argument("Vector addition requires consistent dimensions!");
  Vector result(size, orientation);
for (int i = 0; i < size; i++)
   result[i] = data[i] + other.data[i];
return result;
 }
 // Vector subtraction
 Vector operator- (const Vector& other) const
 {
if (size != other.size)
   throw std::invalid_argument("Vector subtraction requires consistent dimensions");
  Vector result(size, orientation);
for (int i = 0; i < size; i++)
   result[i] = data[i] - other.data[i];
return result;
 }
 // Scalar multiplication (vector × scalar)
 Vector operator* (T scalar) const
 {
  Vector result(size, orientation);
for (int i = 0; i < size; i++)
   result[i] = data[i] * scalar;
return result;
 }
 // Vector dot product (inner product, scalar product, Dot Product)
 T dot(const Vector& other) const
 {
if (size != other.size)
   throw std::invalid_argument("Dot product requires consistent dimensions");
  T sum = 0;
for (int i = 0; i < size; i++)
   sum += data[i] * other.data[i];
return sum;
 }
 // Vector cross product (cross product, vector product, outer product, Cross Product)
 Vector cross(const Vector& other) const
 {
if (size != 3 || other.size != 3)
   throw std::invalid_argument("Cross product is only defined for three-dimensional vectors");
  Vector result(3, orientation);
  result[0] = data[1] * other[2] - data[2] * other[1];
  result[1] = data[2] * other[0] - data[0] * other[2];
  result[2] = data[0] * other[1] - data[1] * other[0];
return result;
 }
 // Vector 1-norm: sum of absolute values
 double norm1() const
 {
  double sum = 0;
for (int i = 0; i < size; i++)
   sum += std::abs(static_cast<double>(data[i]));
return sum;
 }
 // Vector 2-norm: Euclidean norm
 double norm2Value() const
 {
  double sum = 0;
for (int i = 0; i < size; i++)
   sum += static_cast<double> (data[i]) * static_cast<double>(data[i]);
return std::sqrt(sum);
 }
 // Vector maximum norm: ∞-norm, maximum absolute value
 double normInf() const
 {
  double maxVal = 0;
for (int i = 0; i < size; i++)
   maxVal = std::max(maxVal, std::abs(static_cast<double>(data[i])));
return maxVal;
 }
 // Vector p-norm
 double normP(double p) const
 {
if (p < 1)
   throw std::invalid_argument("p-norm must satisfy p >= 1!");
  double sum = 0;
for (int i = 0; i < size; i++)
   sum += pow(std::abs(static_cast<double>(data[i])), p);
return pow(sum, 1.0 / p);
 }
 // Unit vector
 Vector unit() const
 {
  double n = norm2Value();
if (n == 0.0)
   throw std::runtime_error("Zero vector has no unit vector!");
  Vector result(size, orientation);
for (int i = 0; i < size; i++)
   result[i] = static_cast<T>(static_cast<double>(data[i]) / n);
return result;
 }
 // Opposite vector
 Vector opposite() const
 {
  Vector result(size, orientation);
for (int i = 0; i < size; i++)
   result[i] = -data[i];
return result;
 }
};

8. Example

#include <iostream>
#include "Array.h"
#include "Vector.h"
#include <initializer_list> // Supports initialization list {a, b, c}
using namespace std;

int main()
{
 Vector<double> v1 = { {3, 4, 5}, COL };
 cout << "v1 vector:" << endl;
 v1.print();
 cout << " " << endl;

 Vector<double> v3 = { {1, 2, 3}, COL };
 cout << "v3 vector:" << endl;
 v3.print();
 cout << " " << endl;

 cout << "v1's unit vector:" << endl;
 v1.unit().print();
 cout << " " << endl;

 cout << "v1's opposite vector:" << endl;
 v1.opposite().print();
 cout << " " << endl;

 cout << "Vector dot product:" << endl;
 cout << v1.dot(v3) << endl;
 cout << " " << endl;

 cout << "Vector cross product:" << endl;
 v1.cross(v3).print();
 cout << " " << endl;

 cout << "Vector scalar multiplication:" << endl;
 (v1 * 2).print();
 cout << " " << endl;

 cout << "v1's 1-norm" << v1.norm1() << endl;
 cout << " " << endl;

 cout << "v1's 2-norm" << v1.norm2Value() << endl;
 cout << " " << endl;

 cout << "v1's ∞-norm" << v1.normInf() << endl;
 cout << " " << endl;

 cout << "v1's 3-norm" << v1.normP(3.0) << endl;
 cout << " " << endl;

return 0;
}

Results

v1 vector:
[3]
[4]
[5]

v3 vector:
[1]
[2]
[3]

v1's unit vector:
[0.424264]
[0.565685]
[0.707107]

v1's opposite vector:
[-3]
[-4]
[-5]

Vector dot product:
26

Vector cross product:
[2]
[-4]
[2]

Vector scalar multiplication:
[6]
[8]
[10]

v1's 1-norm12

v1's 2-norm7.07107

v1's ∞-norm5

v1's 3-norm6

9. ConclusionThis article implements basic vector operations using C++ template classes and demonstrates the correspondence between algebraic operations and geometric meanings. Such implementations can serve as foundational modules for numerical computation, matrix library development, and algorithm research, with good extensibility and application value.

Leave a Comment