Solving a simple matrix in row-reduced form in C++ - c++

Okay, I am pulling out all my hair on this one, though, as a noob, I am sure there are several problems. I want to take a matrix and, by sing elementary row operations, reduced it to row-reduced echelon form. We assume (1) it is solvable and (2) a unique solution. There is no checking for zeros or anything; it just does row operations. Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
void printmatrix(float A[][4]);
void RowReduce (float A[][4]);
int main() {
// answer should be { 2, 4, -3 }
float A[3][4] = {
{ 5, -6, -7, 7 },
{ 3, -2, 5, -17 },
{ 2, 4, -3, 29 }
};
printmatrix(A);
RowReduce(A);
}
// Outputs the matrix
void printmatrix(float A[][4]) {
int p = 3;
int q = 4;
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
void RowReduce (float A[][4]){
//rows
int p = 3;
//columns
int q = 4;
// the determines the column we are at which holds the diagonal,
// the basis for all elimination above and below
int lead = 0;
cout << endl;
while ( lead < q - 1 ) {
// for each row . . .
for (int i = 0; i < p; i++) {
// ignore the diagonal, and we will not have a tree rref
// as the diagonal will not be divided by itself. I can fix that.
if ( i != lead ) {
cout << A[lead][lead] << " " << A[i][lead];
for (int j = 0; j < q; j++) {
//here is the math . . . . probably where the problem is?
A[i][j] = A[lead][lead] * A[i][j];
A[i][lead] = A[i][lead] * A[lead][j];
A[i][j] = A[i][j] - A[i][lead];
}
cout << endl;
}
}
// now go to the next pivot
lead++;
cout << endl;
}
}
I tried doing it by hand, but what I get is, of course, the right answer, but this gets a diagonal matrix--which is great--but the wrong answer!

The main error in you code is that you are calculating the divisor or multiplier within the for loop. You should calculate them before iterating over the cells.
Hint: debugging is easier if the code is well formated and the variables have meaningful names.
See the implementation of RowReduce():
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
void printmatrix(float A[][4]);
void RowReduce(float A[][4]);
int main()
{
float A[3][4] = {{5, -6, -7, 7},
{3, -2, 5, -17},
{2, 4, -3, 29}}; //answer should be {2, 4, -3}
printmatrix(A);
RowReduce(A);
}
void printmatrix(float A[][4]) // Outputs the matrix
{
int p=3;
int q=4;
for (int i=0; i<p; i++) {
for (int j=0; j<q; j++) {
cout << setw(7) << setprecision(4) << A[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void RowReduce(float A[][4])
{
const int nrows = 3; // number of rows
const int ncols = 4; // number of columns
int lead = 0;
while (lead < nrows) {
float d, m;
for (int r = 0; r < nrows; r++) { // for each row ...
/* calculate divisor and multiplier */
d = A[lead][lead];
m = A[r][lead] / A[lead][lead];
for (int c = 0; c < ncols; c++) { // for each column ...
if (r == lead)
A[r][c] /= d; // make pivot = 1
else
A[r][c] -= A[lead][c] * m; // make other = 0
}
}
lead++;
printmatrix(A);
}
}
The output:
5 -6 -7 7
3 -2 5 -17
2 4 -3 29
1 -1.2 -1.4 1.4
0 1.6 9.2 -21.2
0 6.4 -0.2 26.2
1 0 5.5 -14.5
0 1 5.75 -13.25
0 0 -37 111
1 0 0 2
0 1 0 4
0 0 1 -3

Related

Knight's Tour - I can't make the knight covers the board fully

I am new to C++ and few days ago I chose Knight's Tour to practice backtracking. This program runs well when the knight doesn't have to visit each tiles, they can even miss 1 or 2 tiles and the program still works. But when it comes to the point that I have to cover the whole board, the program seems to enter infinite loop. (Yes I did tried to debug it but I still didn't figure it out)
Note: the starting position of the Knight is always [1; 1]
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
#include <iomanip>
using namespace std;
int n, moves[100][100];
void Import()
{
ifstream f;
f.open("Knight's Tour.inp");
f >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) moves[i][j] = -1;
f.close();
}
bool If_Knight_Moves_Possible(int x, int y)
{
return (x >= 1 && y >= 1 && x <= n && y <= n && moves[x][y] == -1);
}
bool All_Knight_Conditions_Met(int x, int y, int ways_of_x[], int ways_of_y[], int moves_count)
{
if (moves_count > (n * n)) return(1);
// If you input n = 7, you minus (n * n) by 1 and the code works, for n = 8, you minus it by 2
for (int i = 1; i <= n; i++)
{
long int next_x = x + ways_of_x[i], next_y = y + ways_of_y[i];
if (If_Knight_Moves_Possible(next_x, next_y))
{
moves[next_x][next_y] = moves_count;
if (All_Knight_Conditions_Met(next_x, next_y, ways_of_x, ways_of_y, moves_count + 1)) return(1);
else moves[next_x][next_y] = -1;
}
}
return(0);
}
void Analysis()
{
}
void Export()
{
ofstream f("Knight's Tour.out");
int ways_of_x[8] = { -1, -2, -2, -1, 1, 2, 2, 1 };
int ways_of_y[8] = { -2, -1, 1, 2, 2, 1, -1, -2 };
moves[1][1] = 1;
if (All_Knight_Conditions_Met(1, 1, ways_of_x, ways_of_y, 2))
{
f << "There is a possible solution:" << endl;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
f << setw(2) << moves[i][j] << " ";
f << endl;
}
}
else f << "There is no possible solution";
f.close();
}
int main()
{
Import();
Analysis();
Export();
}

How do I print out the value that make magic square?

I have tried this code that I found online and it worked, but I want it to print out which number makes magic square. In this case it is 83, so instead of cout<<"Magic Square", how do I change it to show 83 instead?
Thank you in advance.
# define my_sizeof(type) ((char *)(&type+1)-(char*)(&type))
using namespace std;
// Returns true if mat[][] is magic
// square, else returns false.
bool isMagicSquare(int mat[][3])
{
int n = my_sizeof(mat)/my_sizeof(mat[0]);
// calculate the sum of
// the prime diagonal
int i=0,j=0;
// sumd1 and sumd2 are the sum of the two diagonals
int sumd1 = 0, sumd2=0;
for (i = 0; i < n; i++)
{
// (i, i) is the diagonal from top-left -> bottom-right
// (i, n - i - 1) is the diagonal from top-right -> bottom-left
sumd1 += mat[i][i];
sumd2 += mat[i][n-1-i];
}
// if the two diagonal sums are unequal then it is not a magic square
if(sumd1!=sumd2)
return false;
// For sums of Rows
for (i = 0; i < n; i++) {
int rowSum = 0, colSum = 0;
for (j = 0; j < n; j++)
{
rowSum += mat[i][j];
colSum += mat[j][i];
}
if (rowSum != colSum || colSum != sumd1)
return false;
}
return true;
}
// driver program to
// test above function
int main()
{
int mat[3][3] = {{ 1, 5, 6 },
{ 8, 2, 7 },
{ 3, 4, 9 }};
if (isMagicSquare(mat))
cout << "Magic Square";
else
cout << "Not a magic Square";
return 0;
}
As per suggested, I have tried to change it to:
int main()
{
int mat[3][3] = {{ 1, 5, 6 },
{ 8, 2, 7 },
{ 3, 4, 9 }};
if (isMagicSquare(mat))
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
cout<< mat[i][j] << ' ';
}
cout<< endl;
}
}
else
cout << "Not a magic Square";
return 0;
}
But it showed the whole array instead of the correct index in the array. I am sorry, I am somewhat new at the whole thing.
The result is showing up as:
1 5 6
8 2 7
3 4 9
Did I changed it in the wrong place? Or is there any further reading that I should read. Any helps would be appreciate.
The result that I am expecting is
83
as it is the number in the index that is the magic number.
If the given square is a magic square, that means when isMagicSquare(mat) is true, then iterate through the given square and print each of the values.
To do that, you'll have to learn how to print a 2D array.
In your case, you can do like below:
if (isMagicSquare(mat))
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
cout<< mat[i][j] << ' ';
}
cout<< endl;
}
}
Please check the below resources to learn more about 2D array:
How to print 2D Arrays in C++
Two Dimensional Array in C++
Multidimensional Arrays in C / C++

How to remove duplicate elements from a c++ Bidimensional array

When creating and duplicating the matrix, it writes it the way I want, my question is how can I eliminate the duplicate elements of matrix1 because I need it to only show me the values of the matrix without showing the duplicates. It would be more or less as follows.
enter number of rows: 3.
enter number of columns: 4.
Original Array:.
3 7 14 2.
6 2 3 15.
10 8 11 6.
Result Array:
3.
7.
14.
2.
6.
15.
10.
8.
11.
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
int f = 0;
int c = 0;
cout<<"Ingresar numero de filas: ";
cin>>f;
cout<<"Ingresar numero de columnas: ";
cin>>c;
int matriz[f][c];
int matriz1[f][c];
srand(time(0));
for (int i = 0 ; i < f; i++ )
for (int j = 0 ; j < c ; j++ )
matriz[i][j] = 1 + rand()% 15;
cout<< "Arreglo Original"<< endl;
for (int i = 0 ; i < f; i++ ){
for (int j = 0 ; j < c ; j++ ){
cout<<matriz[i][j]<<" "; }
cout<< endl;
}
cout<< "Arreglo resultante "<<endl;
for (int i = 0 ; i < f; i++ ){
for (int j = 0 ; j < c ; j++ ){
matriz1[i][j] = matriz[i][j];
cout<< matriz1[i][j]<<endl;}
}
return 0;
}
Here you are:
#include <vector>
#include <memory>
#include <bitset>
#include <algorithm>
#include <iterator>
#include <iostream>
int main() {
std::vector<std::vector<int>> example{
{ 3, 7, 14, 2 },
{ 6, 2, 3, 15 },
{ 10, 8, 11, 6 }
};
int const max = 15; // while reading example find out max
auto is_avail = std::make_unique<std::bitset<max + 1>>();
std::vector<int> ans;
for (auto const& v : example) {
for (auto const e : v) {
if (!is_avail->test(e)) {
ans.emplace_back(e);
is_avail->set(e, true);
}
}
}
std::copy(ans.cbegin(), ans.cend(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
In case you want ans to be 2D too replace the code following the line
auto is_avail = std::make_unique<std::bitset<max + 1>>();
with
std::vector<std::vector<int>> ans{ example };
for (auto& v : ans) {
for (auto& e : v) {
if (!is_avail->test(e)) {
is_avail->set(e, true);
}
else {
e = -1; // error state
}
}
}
for (auto const& v : ans) {
for (auto const e : v) {
if (e != -1) {
std::cout << std::setw(2) << e;
}
else {
std::cout << std::setw(2) << ' ';
}
std::cout << '\t';
}
std::cout << '\n';
}
and don't forget to
#include <iomanip>
for std::setw.

Flowchart Algorithm | Find Matrix in Cpp from Array

I have come across this exercise on the topic of Algorithms, using Flowchart to present and test the sum of the matrix rows separately.
The Exercise with Matric
0
1
-2
-2
2
5
1
3
-1
Until now, I don't know to calculate the matric with Flowchart, can you guys help me? It would be nice if you do that using Flowgorithm Application or any other similar app.
The results should be :
For the first row: -1
For the second: 5
For the third: 3
I did this, but I don't know how to optimize the code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int rreshti[9] = {
0, 1, -2,
-2, 2, 5,
1, 3, -1,
};
int r1, r2, r3;
r1 = 0;
r2 = 0;
r3 = 0;
for(int i = 0; i <= 2; i++) {
r1 = r1 + rreshti[i];
};
cout << "Totali i reshtit te pare: " << r1 << endl;
for (int i = 3; i <= 5; i++) {
r2 = r2 + rreshti[i];
};
cout << "Totali i reshtit te pare: " << r2 << endl;
for (int i = 6; i <= 8; i++) {
r3 = r3 + rreshti[i];
};
cout << "Totali i reshtit te pare: " << r3 << endl;
return 0;
}
You can use nested loops as you would have used in a 2D matrix.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int no_of_rows = 3; // I would reccommend you to replace constants and use variables like this.
int no_of_cols = 3;
int rreshti[no_of_rows * no_of_cols] = {
0, 1, -2,
-2, 2, 5,
1, 3, -1,
};
vector<int> rowSum(no_of_rows, 0);
for(int i = 0; i < no_of_rows; i++){
for(int j = 0; j < no_of_cols; j++){
rowSum[i] += rreshti[i*no_of_cols + j];
}cout<<"Sum of row no. "<<(i+1)<<" is = "<<rowSum[i]<<endl;
}
return 0;
}

Array that fills using a loop *AND swaps

I did this program in class and I'm trying to recreate it for an exam coming up. The program is supposed to be an array[2][10] and is supposed to output numbers in this order:
1 3 5 7 9 11 13 15 17 19
0 2 4 6 8 10 12 14 16 18
I'm really lost on this and I could really use any help.
#include<iostream>
#include <string>
#include <cstring>
using namespace std;
void out(int n[2][10]);
void fillit(int n[2][10]);
int main(){
int nums[2][10];
fillit(nums);
out(nums);
}
void fillit(int n[2][10]){
n[0][0] = 1;
n[1][0] = 0;
for (int i = 1; i < 10; i++){
n[0][i] = n[0][i] + 2;
n[1][i] = n[0][i] + 2;
}
}
void out(int n[2][10]){
for (int r = 0; r <= 1; r++){
for (int c = 0; c <= 9; c++){
cout << n[r][c];
}
cout << endl;
}
}
Update I have the program successfully filling the array but now I need the program to swap row 1 with row 2 and then output the new array. I.e.
0 2 4 6 8 10 12 14 16 18
1 3 5 7 9 11 13 15 17 19
void fillit(int n[2][10]){
for (int i = 0; i < 10; i++){
n[0][i] = (i * 2 ) + 1;
n[1][i] = i * 2;
}
}
#include<iostream>
#include <string>
#include <cstring>
using namespace std;
void out(int n[2][10]);
void fillit(int n[2][10]);
int main(){
int nums[2][10];
fillit(nums);
out(nums);
}
void fillit(int n[2][10]){
n[0][0] = 1;
n[1][0] = 0;
for (int i = 1; i < 10; i++){
n[0][i] = n[0][i-1] + 2;
n[1][i] = n[0][i-1] + 2;
}
}
void out(int n[2][10]){
for (int r = 0; r <= 1; r++){
for (int c = 0; c <= 9; c++){
cout << n[r][c];
}
cout << endl;
}
}
How about this, its shorter?
int nums[2][10];
for (int i = 0; i < 20; i++)
{
nums[(i%2)^1][i/2] = i;
}
I noticed that second array elements are even numbers, and the first array corresponding elements are one bigger (and thus odd) ... so this answer accomplishes using ONLY addition. Might be easier to understand.
void fillit(int n[2][10])
{
int even = 0; // start value
for (size_t i = 0; i < 10; i++)
{
int odd = even + 1;
n[0][i] = odd;
n[1][i] = even;
even += 2;
}
}
I noticed that you tagged this problem with C++. Perhaps you should try vectors.
For small vectors, you simply declare with initial values in curly-braces, making it easy to define the matrix limits [2] and [10]. In this example, I initialized using easy to recognize values, so you can tell the 2x10 matrix has not yet been filled. Without this init, the values contained will be random noise.
std::vector<std::vector<int>> n {
{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }, // row 1
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 } // row 2
// 1 2 3 4 5 6 7 8 9 10 <-- col
};
Yes, you could write in the target value of your output, but then fillit() would not be needed.
For passing the 2x10 vector to fillIt(), remember that you need to mark the matrix as a reference. The following emphasizes that n[0] contains odd numbers, and n[1] contains 10 even numbers.
// vector x vector v--reference
void fillIt(std::vector<std::vector<int>>& n)
{
int even = 0;
for (size_t c = 0; c < 10; ++c) // row major {
int odd = even + 1;
n[0][c] = odd;
n[1][c] = even;
even += 2;
}
}
For test, I recommend just passing the 2x10 vector to a new function "showIt()".
// do not modify--vvvvv do not copy--v
void vec2x10Show (const std::vector<std::vector<int>>& n)
{
// header
std::cout << "\nCOL->";
for (int i=0; i<10; ++i) std::cout << std::setw(3) << i+1 << " ";
std::cout << "\nr1: "; // r c
for (int c=0; c<10; ++c) std::cout << std::setw(3) << n[0][c] << " ";
std::cout << "\nr2: "; // r c
for (int c=0; c<10; ++c) std::cout << std::setw(3) << n[1][c] << " ";
std::cout << std::endl;
}
Note the hard coded '10' in each loop (a magic number). Using vectors, this magic number is not necessary because the vector includes this information (your next assignment).