Solve Ax = b, A = lower triangular matrix in c++ - c++

I`m trying to do this function that solves linear systems, A*x = b, where A = lower triangular matrix, linear independent matrix and with only one solution.
But the results always show 0 0 0 0 ...
I have printed the sum, s, and it always shows 0 as well...
#include <iostream>
using namespace std;
void solve(int n, float a[][MAX], float b[], float x[]){
int i,j;
float s;
for(i = 0; i < n; i++){
s = 0;
for(j = 0; j < n; j++){
s = s + a[i][j]*x[j];
cout<<s<<endl;
}
x[i] = (b[i] - s)/a[i][i];
}
}

void solve(int n, float a[][MAX], float b[], float x[]){
int i,j;
float s;
for(i = 0; i < n; i++) {
s = 0;
for(j = 0; j < i; j++) {
^
s = s + a[ i][ j] * x[ j];
}
x[ i] = ( b[ i] - s) / a[ i][ i];
}
}
BackSubstitution.pdf
compiled example

This line:
for(j = 0; j < n; j++){
Should be:
for(j = 0; j < i; j++){
Then it works fine - assuming your pivots are always non zero.

Related

C++ Gauss–Seidel method

this is a piece of code for a simple iteration method for solving systems of linear algebraic equations:
double* iter(double** a, double* y, int n, int& iter)
{
double* res = new double[n];
int i, j;
for (i = 0; i < n; i++)
{
res[i] = y[i] / a[i][i];
}
double eps = 0.0001;
double* Xn = new double[n];
do {
iter++;
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < n; j++) {
if (i == j)
continue;
else {
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
}
bool flag = true;
for (i = 0; i < n - 1; i++) {
if (fabs(Xn[i] - res[i]) > eps) {
flag = false;
break;
}
}
for (i = 0; i < n; i++) {
res[i] = Xn[i];
}
if (flag)
break;
} while (1);
return res;
}
and formula for it:
but I would like to implement the seidel method.and slightly changed the code according to the formula below
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < i-1; j++) {
Xn[i] -= a[i][j] / a[i][i] * Xn[j];
}
for (j = i+1; j < n; j++){
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
but I'm not getting exactly what I expected:
I would be grateful if you could tell me where I made a mistake. thank you in advance for your answers.
Your mistake lies in the new implementation.
The first sum of the Seidel method sums up to the element before the diagonal, while your for loop goes up to two elements before the diagonal.
Instead of
for(j = 0; j < i-1; j++)
you should have
for(j = 0; j < i; j++)
Note that Gauss Seidel method is applicable if the elements on the diagonal are non-zero.

Find the sum of an entire matrix using functions (C++)

I am writing some code that writes a matrix with a 10x10 size and prints it using functions. What I need is a function that takes the sum of the entire matrix array. What I have done is that I tried to sum up each row and column separately and add the total together. The problem with mine is that I believe that it only prints out the sum of the row or the column.
This is the code I have:
#include <iostream>
#include <ctime>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int ROW_SIZE = 10;
const int COLUMN_SIZE = 10;
void initialize(int [][10], int, int);
void display(int matrix[][10], int, int);
void sum(int matrix[][COLUMN_SIZE], int, int);
int main() {
int matrix [ROW_SIZE][COLUMN_SIZE];
initialize(matrix, ROW_SIZE, COLUMN_SIZE);
display(matrix, ROW_SIZE,COLUMN_SIZE);
sum(matrix, ROW_SIZE,COLUMN_SIZE);
return 0;
}
void initialize(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
for (int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
matrix[i][j] = 1 + rand() % 99;
}
}
}
void display(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
cout<< setw(4)<<matrix[i][j]<< " ";
}
cout<< endl;
}
}
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row;
int sum_col;
for(int i = 0; i < ROW_SIZE; i++){
int sum_row = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_row = sum_row + matrix[i][j];
}
}
for(int i = 0; i < ROW_SIZE; i++){
int sum_col = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_col = sum_col + matrix[i][j];
}
}
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
What you have done is sum of last row + last column. This should be enough:
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum = 0;
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
sum += matrix[i][j];
}
}
cout<<"The sum of the matrix is "<<sum<< endl;
}
few early problems in your code
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row; // uninitialized make it equal to 0
int sum_col; // uninitialized make it equal to 0
for(int i = 0; i < ROW_SIZE; i++){
int sum_row = 0; // This is local to block and masks the sum_row above
for(int j = 0; j < COLUMN_SIZE; j++){
sum_row = sum_row + matrix[i][j];
}
}
for(int i = 0; i < ROW_SIZE; i++){
int sum_col = 0;
for(int j = 0; j < COLUMN_SIZE; j++){
sum_col = sum_col + matrix[i][j]; //Iterating over rows again matrix[j][i] may be
}
}
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum_row = 0;
int sum_col = 0;
for(int i = 0; i < ROW_SIZE; i++)
for(int j = 0; j < COLUMN_SIZE; j++)
sum_row += matrix[i][j];
for(int i = 0; i < ROW_SIZE; i++)
for(int j = 0; j < COLUMN_SIZE; j++)
sum_col += matrix[j][i];
int sum = sum_row + sum_col;
cout<<"The sum of the matrix is "<<sum<< endl;
}
Now of course the question and logic doesn't seem to co-exist together and if sum of entire matrix means sum of all elements which is what it sounds like it can be achieved with the one here
void sum(int matrix[][COLUMN_SIZE], int ROW_SIZE, int COLUMN_SIZE){
int sum = 0;
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COLUMN_SIZE; j++){
sum += matrix[i][j];
}
}
cout<<"The sum of the matrix is "<<sum<< endl;
}
You're doing something wrong in terms of naming. You have constants called ROW_SIZE and COLUMN_SIZE and then you have parameters with the same names to functions like sum(). This is confusing for something reading your code. Call your parameters something else, like rows and columns.
Here is an alternative to the proposed solutions using std::accumulate().
const int ROW_SIZE = 3;
const int COLUMN_SIZE = 3;
void sum(int matrix[][COLUMN_SIZE], int const rows, int const cols)
{
int sum = std::accumulate(&matrix[0][0], &matrix[rows-1][cols], 0);
std::cout<<"The sum of the matrix is "<<sum<< std::endl;
}
int main()
{
int m[ROW_SIZE][COLUMN_SIZE] {{1,2,3}, {4,5,6}, {7,8,9}};
sum(m, ROW_SIZE, COLUMN_SIZE);
}
std::accumulate() takes the iterators that delimit a range. Those are the iterators to the first element and the one past the last element of the range. In this case, these are &matrix[0][0] and &matrix[row-1][col] (since &matrix[row-1][col-1] is the last element of the matrix). There are other ways to put that, such as the following:
auto begin = std::begin(matrix[0]);
int sum = std::accumulate(begin, begin + rows * cols, 0);

How to Fix LU Decompostion?

I wrote the code according to the algorithm, but the result is incorrect. According to the algorithm, we must indicate the dimension of the matrix and manually fill in the main matrix A and vector B. We need to generate an LU matrix. It is generated, but with the wrong numbers. And in the end we have to get the vector X with solutions. And this is in windowed mode.
https://imgur.com/TSsjMXp
int N = 1; // matrix dimension
double R = 0;
typedef double Matrix [6][6];
typedef double Vec [6];
.
.
.
void Decomp (Matrix A, int N, int &Change)
{
int i, j, k ;
double R, L, U;
Change = 1;
R = Math::Abs(A[1][1]);
for(j=2; j<=N; j++)
if (Math::Abs(A[j][1])>= R)
{
Change = j;
R = Math::Abs(A[j][1]);
}
if (R<= 1E-7)
{
MessageBox::Show("The system is degenerate");
}
if (k!=1)
{
for(i=1; i<=N; i++)
{
R = A[Change][i];
A[Change][i] = A[1][i];
A[1][i] = R;
}
}
for(i=2; i<=N; i++)
A[1][i] = A[1][i]/A[1][1];
for(i=2; i<=N; i++)
{
for(k=i; k<=N; k++);
{
R = 0;
for ( j=1; j<=(i-1); j++)
R = R + A[k][j] * A[j][i];
A[k][i] = A[k][i] - R;
}
if (A[i][i]<= 1E-7)
{
MessageBox::Show("The system is degenerate[enter image description here][1]");
}
for(k = i+1; k<=N; k++)
{
R = 0;
for (j=1; j<=(i-1); j++)
R = R + A[i][j] * A[j][k];
A[i][k] = (A[i][k] - R) / A[i][i];
}
}
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
C_matrix_dgv->Rows[i]->Cells[j] -> Value = Convert::ToString(A[i+1][j+1]);
}
}
void Solve (Matrix A, Vec b, Vec x, int Change, int N)
{
int i = 0,j = 0;
double R;
if (Change!=1)
{
R = b[Change];
b[Change] = b[1];
b[1] = R;
}
b[1] = b[1]/A[1][1];
for(i=2; i<=N; i++)
{
R = 0;
for( j=1; j<=(i-1); j++)
R = R + A[i][j] * b[j];
b[i] = (b[i] - R) / A[i][i];
}
x[N] = b[N];
for( i=1; i<=(N-1); i++)
{
R = 0;
for(j = (N+1-i); j<=N; j++)
R = R + A[N - i][j] * x[j];
x[N - i] = b[N - i] - R;
}
}
int N = 1; // matrix dimension
If you use this in the rest of the code you cannot get correct results. The dimension of the matrix is 6x6. Use a std::array or std::vector so that you dont need to keep the size in a seperate variable.

Partial Pivoting/Gaussian elimination- swapping columns instead of rows producing wrong output

I'm trying to implement a quick program to solve a system of linear equations. The program reads the input from a file and then writes the upper-triangular system and solutions to a file. It is working with no pivoting, but when I try to implement the pivoting it produces incorrect results.
As example input, here is the following system of equations:
w+2x-3y+4z=12
2w+2x-2y+3z=10
x+y=-1
w-x+y-2z=-4
I expect the results to be w=1, x=0, y=-1 and z=2. When I don't pivot, I get this answer (with some rounding error on x). When I add in the pivoting, I get the same numbers but in the wrong order: w=2,x=1,y=-1 and z=0.
What do I need to do to get these in the correct order? Am I missing a step somewhere? I need to do column swapping instead of rows because I need to adapt this to a parallel algorithm later that requires that. Here is the code that does the elimination and back substitution:
void gaussian_elimination(double** A, double* b, double* x, int n)
{
int maxIndex;
double temp;
int i;
for (int k = 0; k < n; k++)
{
i = k;
for (int j = k+1; j < n; j++)
{
if (abs(A[k][j]) > abs(A[k][i]))
{
i = j;
}
}
if (i != k)
{
for (int j = 0; j < n; j++)
{
temp = A[j][k];
A[j][k] = A[j][i];
A[j][i] = temp;
}
}
for (int j = k + 1; j < n; j++)
{
A[k][j] = A[k][j] / A[k][k];
}
b[k] = b[k] / A[k][k];
A[k][k] = 1;
for (i = k + 1; i < n; i++)
{
for (int j = k + 1; j < n; j++)
{
A[i][j] = A[i][j] - A[i][k] * A[k][j];
}
b[i] = b[i] - A[i][k] * b[k];
A[i][k] = 0;
}
}
}
void back_substitution(double**U, double*x, double*y, int n)
{
for (int k = n - 1; k >= 0; k--)
{
x[k] = y[k];
for (int i = k - 1; i >= 0; i--)
{
y[i] = y[i] - x[k]*U[i][k];
}
}
}
I believe what you implemented is actually complete pivoting.
With complete pivoting, you must keep track of the permutation of columns, and apply the same permutation to your answer.
You can do this with an array {0, 1, ..., n}, where you swap the i'th and k'th values in the second loop. Then, rearange the solution using this array.
If what you were trying to do is partial pivoting, you need to look for the maximum in the respective row, and swap the rows and the values of 'b' accordingly.

Sort Diagonally Two Dimensional Array

Firstly I created my two dimensional array, then I translated it to one dimensional array and I bubble sorted the 1D array, but after I didn't find the pattern to bring it back to 2D array diagonally sorted.
#include<iostream>
#include<iomanip>
const int r = 10;
const int c = 10;
const int lim = r * c;
int A[r][c] = { 0 };
int B[lim];
using namespace std;
void generatearray(int A[][], int r, int c){
srand(time(NULL));
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
A[i][j] = rand() % lim;
}
}
}
void transformingto1Darray(int A[r][c], int b[lim]){
int p = 0;
for (int m = 0; m < r; m++){
for (int n = 0; n < c; n++){
B[p] = A[m][n];
p++;
}
}
}
void sorting1Darray(int B[][]){
int temp = 0;
for (int k = 0; k < lim - 1; k++){
for (int i = 0; i < lim - 1; i++)
if (B[i] > B[i + 1]){
temp = B[i];
B[i] = B[i + 1];
B[i + 1] = temp;
}
}
}
void sortingdiagonally2Darray(int A[][], int B[]){
int main{
generatearray(A);
transformingto1Darray(A, B);
sorting1Darray(B);
sortingdiagonally2Darray(A, B);
return 0;
}
It's a bit of a wonky solution but it dose work. Because of the way multidimensional indexing works the value in B[i] will be equal to the value in A[0][i].
In your case you want something like this in your sortingdiagonally2Darray function.
for (int i = 0; i > r * c; i++) {
A[0][i] = B[i];
}
This works because under the hood arrays are just pointers. B[x] is syntactic sugar for *(B + x) and A[0][x] will equate to *(*(A + 0) + x) because it's a pointer to a pointer (hence the double star/double brackets).