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

Gram Schmidt Orthogonalisation Process More...

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

Namespaces

 linear_algebra
 Linear Algebra algorithms.
 
 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
88  {
89  for (int i = 0; i < r; ++i) {
90  std::cout << "Vector " << i + 1 << ": ";
91  for (int j = 0; j < c; ++j) {
92  std::cout << B[i][j] << " ";
93  }
94  std::cout << '\n';
95  }
96 }

◆ 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
53  {
54  double sum = 0;
55  for (int i = 0; i < c; ++i) {
56  sum += x[i] * y[i];
57  }
58  return sum;
59 }
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

108  {
109  if (c < r) { /// we check whether appropriate dimensions are given or not.
110  std::cout
111  << "Dimension of vector is less than number of vector, hence \n first "
112  << c << " vectors are orthogonalised\n";
113  r = c;
114  }
115 
116  int k = 1;
117 
118  while (k <= r) {
119  if (k == 1) {
120  for (int j = 0; j < c; j++) B[0][j] = A[0][j]; ///First vector is copied as it is.
121  }
122 
123  else {
124  std::array<double, 10> all_projection{}; ///array to store projections
125  for (int i = 0; i < c; ++i) {
126  all_projection[i] = 0; ///First initialised to zero
127  }
128 
129  int l = 1;
130  while (l < k) {
131  std::array<double, 10> temp{}; ///to store previous projected array
132  double factor; ///to store the factor by which the previous array will change
133  factor = projection(A[k - 1], B[l - 1], c);
134  for(int i = 0; i < c; ++i)
135  temp[i] = B[l - 1][i] * factor; ///projected array created
136  for (int j = 0; j < c; ++j) {
137  all_projection[j] = all_projection[j] + temp[j]; ///we take the projection with all the previous vector and add them.
138  }
139  l++;
140  }
141  for (int i = 0; i < c; ++i) {
142  B[k - 1][i] = A[k - 1][i] - all_projection[i]; ///subtract total projection vector from the input vector
143  }
144  }
145  k++;
146  }
147  display(r, c, B); //for displaying orthogoanlised vectors
148 }
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

213  {
214  int r=0, c=0;
215  test(); // perform self tests
216  std::cout << "Enter the dimension of your vectors\n";
217  std::cin >> c;
218  std::cout << "Enter the number of vectors you will enter\n";
219  std::cin >> r;
220 
222  A{}; ///a 2-D array for storing all vectors
224  {0}}; /// a 2-D array for storing orthogonalised vectors
225  /// storing vectors in array A
226  for (int i = 0; i < r; ++i) {
227  std::cout << "Enter vector " << i + 1 <<'\n'; ///Input of vectors is taken
228  for (int j = 0; j < c; ++j) {
229  std::cout << "Value " << j + 1 << "th of vector: ";
230  std::cin >> A[i][j];
231  }
232  std::cout <<'\n';
233  }
234 
236 
237  double dot = 0;
238  int flag = 1; ///To check whether vectors are orthogonal or not
239  for (int i = 0; i < r - 1; ++i) {
240  for (int j = i + 1; j < r; ++j) {
241  dot = fabs(linear_algebra::gram_schmidt::dot_product(B[i], B[j], c));
242  if (dot > 0.1) /// take make the process numerically stable, upper bound for the dot product take 0.1
243  {
244  flag = 0;
245  break;
246  }
247  }
248  }
249  if (flag == 0) std::cout << "Vectors are linearly dependent\n";
250  return 0;
251 }
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.

72  {
73  double dot = dot_product(x, y, c); ///The dot product of two vectors is taken
74  double anorm = dot_product(y, y, c); ///The norm of the second vector is taken.
75  double factor = dot / anorm; ///multiply that factor with every element in a 3rd vector, whose initial values are same as the 2nd vector.
76  return factor;
77 }
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
155  {
157  {{1, 0, 1, 0}, {1, 1, 1, 1}, {0, 1, 2, 1}}};
158  std::array<std::array<double, 10>, 20> b1 = {{0}};
159  double dot1 = 0;
161  int flag = 1;
162  for (int i = 0; i < 2; ++i)
163  for (int j = i + 1; j < 3; ++j) {
164  dot1 = fabs(linear_algebra::gram_schmidt::dot_product(b1[i], b1[j], 4));
165  if (dot1 > 0.1) {
166  flag = 0;
167  break;
168  }
169  }
170  if (flag == 0) std::cout << "Vectors are linearly dependent\n";
171  assert(flag == 1);
172  std::cout << "Passed Test Case 1\n ";
173 
174  std::array<std::array<double, 10>, 20> a2 = {{{3, 1}, {2, 2}}};
175  std::array<std::array<double, 10>, 20> b2 = {{0}};
176  double dot2 = 0;
178  flag = 1;
179  for (int i = 0; i < 1; ++i)
180  for (int j = i + 1; j < 2; ++j) {
181  dot2 = fabs(linear_algebra::gram_schmidt::dot_product(b2[i], b2[j], 2));
182  if (dot2 > 0.1) {
183  flag = 0;
184  break;
185  }
186  }
187  if (flag == 0) std::cout << "Vectors are linearly dependent\n";
188  assert(flag == 1);
189  std::cout << "Passed Test Case 2\n";
190 
191  std::array<std::array<double, 10>, 20> a3 = {{{1, 2, 2}, {-4, 3, 2}}};
192  std::array<std::array<double, 10>, 20> b3 = {{0}};
193  double dot3 = 0;
195  flag = 1;
196  for (int i = 0; i < 1; ++i)
197  for (int j = i + 1; j < 2; ++j) {
198  dot3 = fabs(linear_algebra::gram_schmidt::dot_product(b3[i], b3[j], 3));
199  if (dot3 > 0.1) {
200  flag = 0;
201  break;
202  }
203  }
204  if (flag == 0) std::cout << "Vectors are linearly dependent\n" ;
205  assert(flag == 1);
206  std::cout << "Passed Test Case 3\n";
207 }
test
static void test()
Definition: gram_schmidt.cpp:155
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:53
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:71
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:107
std::cin
machine_learning::sum
T sum(const std::vector< std::valarray< T >> &A)
Definition: vector_ops.hpp:232