TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
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:

Go to the source code of this file.

Namespaces

namespace  numerical_methods
 for assert
 
namespace  gram_schmidt
 Functions for Gram Schmidt Orthogonalisation Process
 

Functions

double numerical_methods::gram_schmidt::dot_product (const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
 
double numerical_methods::gram_schmidt::projection (const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)
 
void numerical_methods::gram_schmidt::display (const int &r, const int &c, const std::array< std::array< double, 10 >, 20 > &B)
 
void numerical_methods::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.
 

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

Definition in file gram_schmidt.cpp.

Function Documentation

◆ display()

void numerical_methods::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

Definition at line 101 of file gram_schmidt.cpp.

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 numerical_methods::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

Definition at line 59 of file gram_schmidt.cpp.

60 {
61 double sum = 0;
62 for (int i = 0; i < c; ++i) {
63 sum += x[i] * y[i];
64 }
65 return sum;
66}
T sum(const std::vector< std::valarray< T > > &A)

◆ gram_schmidt()

void numerical_methods::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

Definition at line 121 of file gram_schmidt.cpp.

123 {
124 if (c < r) {
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];
137 }
138
139 else {
140 std::array<double, 10>
141 all_projection{};
142 for (int i = 0; i < c; ++i) {
143 all_projection[i] = 0;
144 }
145
146 int l = 1;
147 while (l < k) {
148 std::array<double, 10>
149 temp{};
150 double factor = NAN;
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;
155 }
156 for (int j = 0; j < c; ++j) {
157 all_projection[j] =
158 all_projection[j] +
159 temp[j];
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];
169 }
170 }
171 k++;
172 }
173 display(r, c, B); // for displaying orthogoanlised vectors
174}
double k(double x)
Another test function.
double l(double x)
Another test function.
double projection(const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)

◆ 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

Definition at line 248 of file gram_schmidt.cpp.

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
256 std::array<std::array<double, 10>, 20>
257 A{};
258 std::array<std::array<double, 10>, 20> B = {
259 {0}};
261 for (int i = 0; i < r; ++i) {
262 std::cout << "Enter vector " << i + 1
263 << '\n';
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;
275 for (int i = 0; i < r - 1; ++i) {
276 for (int j = i + 1; j < r; ++j) {
277 dot = fabs(
278 numerical_methods::gram_schmidt::dot_product(B[i], B[j], c));
279 if (dot > 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}
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)
static void test()

◆ projection()

double numerical_methods::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.

Definition at line 79 of file gram_schmidt.cpp.

80 {
81 double dot =
82 dot_product(x, y, c);
83 double anorm =
84 dot_product(y, y, c);
85 double factor =
86 dot /
87 anorm;
89 return factor;
90}
double dot_product(const std::array< double, 10 > &x, const std::array< double, 10 > &y, const int &c)

◆ test()

static void test ( )
static

Test Function. Process has been tested for 3 Sample Inputs

Returns
void

Definition at line 181 of file gram_schmidt.cpp.

181 {
182 std::array<std::array<double, 10>, 20> a1 = {
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 numerical_methods::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 numerical_methods::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 numerical_methods::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}