Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
gram_schmidt.cpp File Reference

Gram Schmidt Orthogonalisation Process More...

#include <array>
#include <cassert>
#include <cmath>
#include <iostream>
#include "math.h"
Include dependency graph for gram_schmidt.cpp:

Namespaces

 linear_algebra
 for io operations
 
 gram_schmidt
 Functions for Gram Schmidt Orthogonalisation Process
 

Functions

double linear_algebra::gram_schmidt::dot_product (const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
 
double linear_algebra::gram_schmidt::projection (const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
 
void linear_algebra::gram_schmidt::display (const int &r, const int &c, const std::array< std::array< double, 10 >, 20 > &B)
 
void linear_algebra::gram_schmidt::gram_schmidt (int r, const int &c, const std::array< std::array< double, 10 >, 20 > &A, std::array< std::array< double, 10 >, 20 > B)
 
static void test ()
 
int main ()
 Main Function. More...
 

Detailed Description

Gram Schmidt Orthogonalisation Process

Takes the input of Linearly Independent Vectors, returns vectors orthogonal to each other.

Algorithm

Take the first vector of given LI vectors as first vector of Orthogonal vectors. Take projection of second input vector on the first vector of Orthogonal vector and subtract it from the 2nd LI vector. Take projection of third vector on the second vector of Othogonal vectors and subtract it from the 3rd LI vector. Keep repeating the above process until all the vectors in the given input array are exhausted.

For Example: In R2, Input LI Vectors={(3,1),(2,2)} then Orthogonal Vectors= {(3, 1),(-0.4, 1.2)}

Have defined maximum dimension of vectors to be 10 and number of vectors taken is 20. Please do not give linearly dependent vectors

Author
Akanksha Gupta

Function Documentation

◆ display()

void linear_algebra::gram_schmidt::display ( const int &  r,
const int &  c,
const std::array< std::array< double, 10 >, 20 > &  B 
)

Function to print the orthogonalised vector

Parameters
rnumber of vectors
cdimenaion of vectors
Bstores orthogonalised vectors
Returns
void
102  {
103  for (int i = 0; i < r; ++i) {
104  std::cout << "Vector " << i + 1 << ": ";
105  for (int j = 0; j < c; ++j) {
106  std::cout << B[i][j] << " ";
107  }
108  std::cout << '\n';
109  }
110 }

◆ dot_product()

double linear_algebra::gram_schmidt::dot_product ( const std::array< double, 10 > &  x,
const std::array< double, 10 > &  y,
const int &  c 
)

Dot product function. Takes 2 vectors along with their dimension as input and returns the dot product.

Parameters
xvector 1
yvector 2
cdimension of the vectors
Returns
sum
60  {
61  double sum = 0;
62  for (int i = 0; i < c; ++i) {
63  sum += x[i] * y[i];
64  }
65  return sum;
66 }
Here is the call graph for this function:

◆ gram_schmidt()

void linear_algebra::gram_schmidt::gram_schmidt ( int  r,
const int &  c,
const std::array< std::array< double, 10 >, 20 > &  A,
std::array< std::array< double, 10 >, 20 >  B 
)

Function for the process of Gram Schimdt Process

Parameters
rnumber of vectors
cdimension of vectors
Astores input of given LI vectors
Bstores orthogonalised vectors
Returns
void

we check whether appropriate dimensions are given or not.

First vector is copied as it is.

array to store projections

First initialised to zero

to store previous projected array

to store the factor by which the previous array will change

projected array created

we take the projection with all the previous vector and add them.

subtract total projection vector from the input vector

123  {
124  if (c < r) { /// we check whether appropriate dimensions are given or not.
125  std::cout << "Dimension of vector is less than number of vector, hence "
126  "\n first "
127  << c << " vectors are orthogonalised\n";
128  r = c;
129  }
130 
131  int k = 1;
132 
133  while (k <= r) {
134  if (k == 1) {
135  for (int j = 0; j < c; j++)
136  B[0][j] = A[0][j]; /// First vector is copied as it is.
137  }
138 
139  else {
141  all_projection{}; /// array to store projections
142  for (int i = 0; i < c; ++i) {
143  all_projection[i] = 0; /// First initialised to zero
144  }
145 
146  int l = 1;
147  while (l < k) {
149  temp{}; /// to store previous projected array
150  double factor = NAN; /// to store the factor by which the
151  /// previous array will change
152  factor = projection(A[k - 1], B[l - 1], c);
153  for (int i = 0; i < c; ++i) {
154  temp[i] = B[l - 1][i] * factor; /// projected array created
155  }
156  for (int j = 0; j < c; ++j) {
157  all_projection[j] =
158  all_projection[j] +
159  temp[j]; /// we take the projection with all the
160  /// previous vector and add them.
161  }
162  l++;
163  }
164  for (int i = 0; i < c; ++i) {
165  B[k - 1][i] =
166  A[k - 1][i] -
167  all_projection[i]; /// subtract total projection vector
168  /// from the input vector
169  }
170  }
171  k++;
172  }
173  display(r, c, B); // for displaying orthogoanlised vectors
174 }
Here is the call graph for this function:

◆ main()

int main ( void  )

Main Function.

Returns
0 on exit

a 2-D array for storing all vectors

a 2-D array for storing orthogonalised vectors

storing vectors in array A

Input of vectors is taken

To check whether vectors are orthogonal or not

take make the process numerically stable, upper bound for the dot product take 0.1

248  {
249  int r = 0, c = 0;
250  test(); // perform self tests
251  std::cout << "Enter the dimension of your vectors\n";
252  std::cin >> c;
253  std::cout << "Enter the number of vectors you will enter\n";
254  std::cin >> r;
255 
257  A{}; /// a 2-D array for storing all vectors
259  {0}}; /// a 2-D array for storing orthogonalised vectors
260  /// storing vectors in array A
261  for (int i = 0; i < r; ++i) {
262  std::cout << "Enter vector " << i + 1
263  << '\n'; /// Input of vectors is taken
264  for (int j = 0; j < c; ++j) {
265  std::cout << "Value " << j + 1 << "th of vector: ";
266  std::cin >> A[i][j];
267  }
268  std::cout << '\n';
269  }
270 
272 
273  double dot = 0;
274  int flag = 1; /// To check whether vectors are orthogonal or not
275  for (int i = 0; i < r - 1; ++i) {
276  for (int j = i + 1; j < r; ++j) {
277  dot =
278  fabs(linear_algebra::gram_schmidt::dot_product(B[i], B[j], c));
279  if (dot > 0.1) /// take make the process numerically stable, upper
280  /// bound for the dot product take 0.1
281  {
282  flag = 0;
283  break;
284  }
285  }
286  }
287  if (flag == 0)
288  std::cout << "Vectors are linearly dependent\n";
289  return 0;
290 }
Here is the call graph for this function:

◆ projection()

double linear_algebra::gram_schmidt::projection ( const std::array< double, 10 > &  x,
const std::array< double, 10 > &  y,
const int &  c 
)

Projection Function Takes input of 2 vectors along with their dimension and evaluates their projection in temp

Parameters
xVector 1
yVector 2
cdimension of each vector
Returns
factor

The dot product of two vectors is taken

The norm of the second vector is taken.

multiply that factor with every element in a 3rd vector, whose initial values are same as the 2nd vector.

80  {
81  double dot =
82  dot_product(x, y, c); /// The dot product of two vectors is taken
83  double anorm =
84  dot_product(y, y, c); /// The norm of the second vector is taken.
85  double factor =
86  dot /
87  anorm; /// multiply that factor with every element in a 3rd vector,
88  /// whose initial values are same as the 2nd vector.
89  return factor;
90 }
Here is the call graph for this function:

◆ test()

static void test ( )
static

Test Function. Process has been tested for 3 Sample Inputs

Returns
void
181  {
183  {{1, 0, 1, 0}, {1, 1, 1, 1}, {0, 1, 2, 1}}};
184  std::array<std::array<double, 10>, 20> b1 = {{0}};
185  double dot1 = 0;
187  int flag = 1;
188  for (int i = 0; i < 2; ++i) {
189  for (int j = i + 1; j < 3; ++j) {
190  dot1 = fabs(
191  linear_algebra::gram_schmidt::dot_product(b1[i], b1[j], 4));
192  if (dot1 > 0.1) {
193  flag = 0;
194  break;
195  }
196  }
197  }
198  if (flag == 0)
199  std::cout << "Vectors are linearly dependent\n";
200  assert(flag == 1);
201  std::cout << "Passed Test Case 1\n ";
202 
203  std::array<std::array<double, 10>, 20> a2 = {{{3, 1}, {2, 2}}};
204  std::array<std::array<double, 10>, 20> b2 = {{0}};
205  double dot2 = 0;
207  flag = 1;
208  for (int i = 0; i < 1; ++i) {
209  for (int j = i + 1; j < 2; ++j) {
210  dot2 = fabs(
211  linear_algebra::gram_schmidt::dot_product(b2[i], b2[j], 2));
212  if (dot2 > 0.1) {
213  flag = 0;
214  break;
215  }
216  }
217  }
218  if (flag == 0)
219  std::cout << "Vectors are linearly dependent\n";
220  assert(flag == 1);
221  std::cout << "Passed Test Case 2\n";
222 
223  std::array<std::array<double, 10>, 20> a3 = {{{1, 2, 2}, {-4, 3, 2}}};
224  std::array<std::array<double, 10>, 20> b3 = {{0}};
225  double dot3 = 0;
227  flag = 1;
228  for (int i = 0; i < 1; ++i) {
229  for (int j = i + 1; j < 2; ++j) {
230  dot3 = fabs(
231  linear_algebra::gram_schmidt::dot_product(b3[i], b3[j], 3));
232  if (dot3 > 0.1) {
233  flag = 0;
234  break;
235  }
236  }
237  }
238  if (flag == 0)
239  std::cout << "Vectors are linearly dependent\n";
240  assert(flag == 1);
241  std::cout << "Passed Test Case 3\n";
242 }
test
static void test()
Definition: gram_schmidt.cpp:181
std::fabs
T fabs(T... args)
linear_algebra::gram_schmidt::dot_product
double dot_product(const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
Definition: gram_schmidt.cpp:59
linear_algebra::gram_schmidt::projection
double projection(const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
Definition: gram_schmidt.cpp:79
std::cout
std::array
STL class.
linear_algebra::gram_schmidt::gram_schmidt
void gram_schmidt(int r, const int &c, const std::array< std::array< double, 10 >, 20 > &A, std::array< std::array< double, 10 >, 20 > B)
Definition: gram_schmidt.cpp:121
std::cin
machine_learning::sum
T sum(const std::vector< std::valarray< T >> &A)
Definition: vector_ops.hpp:232