I am working on a 2D vector of doubles matrix solver and my matrices keep turning out incorrectly.
The intended matrix output at "Level 3" is {(top, left to right)3,4 over (bottom, left to right)1,2} but my code keeps outputting {2,1 over 3,4}. I keep trying to invert the values but whenever I do so I keep getting an out of bounds exception.
vector<double> gauss(mat B) {
int n = B.A.size();
for (int i=0; i<n-1; i++) {
// Search for maximum in this column
double maxEl = abs(B.getSlot(i,i));
int maxRow = i;
for (int k=i+1; k<n; k++) {
if (abs(B.getSlot(k,i)) > maxEl) {
maxEl = abs(B.getSlot(k,i));
maxRow = k;
}
}
// Swap maximum row with current row
for (int k=i; k<n+1;k++) {
double tmp = B.getSlot(k,maxRow);
B.editSlot(k,maxRow,B.getSlot(k,i));
B.editSlot(k,i,tmp);
}
cout << "\n\nlevel 3: \n";
B.display();
}
B.display();
// Solve equation Ax=b for an upper triangular matrix A
vector<double> x(n);
for (int i=n-1; i>=0; i--) {
x[i] = B.getSlot(i,n)/B.getSlot(i,i);
for (int k=i-1;k>=0; k--) {
B.editSlot(k,n,B.getSlot(k,n)-B.getSlot(k,i)*x[i]);
}
}
return x;
}
int main() {
int n = *Size of array is properly retrieved*
mat my_mat(n,n);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(i,j,myDub);
}
}
// Calculate solution
vector<double> x(n);
x = gauss(my_mat);
}
And my class code is as follows
class mat
{
public:
mat(int x,int y){
int row = x;
int col = y;
n=row;
A = vector<vector<double>>(row,vector<double>(row,0));
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
cout<<setw(6)<<A[i][j];
}
cout<<endl;
}
}
void editSlot(int x, int y, double val){A[y][x] = val;}
double getSlot(int x, int y){return A[y][x];}
void display()
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
cout<<setw(6)<<A[j][i];
}
cout<<endl;
}
cout<<endl;
}
vector<vector<double>> A;
private:
int n;
};
Try to change your input loop:
// Read input data
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(j, i, myDub); // < - j, i swapped.
}
}
Can you provide sample input that you use and what output you expect?
Related
I get a segmentation fault when I run the code below.
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
cin>>val;
a[i].push_back(val);
}
}
But when I change it to this, it seems to work. What is the reason?
int main()
{
int R, C, val;
cin>>R>>C;
vector<vector<int>> a;
for(int i = 0; i < R; i++)
{
vector<int>temp;
for(int j = 0; j < C; j++)
{
cin>>val;
temp.push_back(val);
}
a.push_back(temp);
}
I get the same fault no matter what the value of R and C is kept.
You have never told what is the size of vector<vector<int>>, and you try to access a[i].
You have to resize the vector.
int main()
{
int R, C;
std::cin >> R >> C;
std::vector<std::vector<int>> a(R, std::vector<int>(C));
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
std::cin >> a[i][j]; //because we resize the vector, we can do this
}
}
}
In the code below, my aim is to multiply two matrices reflect[3][3] and mat[3][s] where s can be any value 0-10. Here the statement (A) and (B) is not getting printed, please tell me why??
#include<iostream>
# include<math.h>
#include<conio.h>
using namespace std;
int mat[10][10];
int result[3][10];
int reflect[3][3]= {1,0,5,0,1,5,0,0,1};
int i , j,k,s;
void multiply_matrix(int A[3][3], int B[3][10])
{
for(i=0; i<3; i++)
for( j=0; j<10; j++)
result[i][j] = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < s; j++)
{
result[i][j] = 0;
for (k = 0; k < 3; k++)
{
result[i][j]=result[i][j]+(A[i][k]*B[k][j]) ;
}
cout<<result[i][j]<<" ";//------(1)
}
cout<<endl;
}
cout<<"Multiplication after matrix: "<<endl;
for(i=0; i<3; i++)
{
for(j=0; j<s; j++)
{
cout<<result[i][j]<<" ";//------(B)
}
cout<<endl;;
}
}
int main()
{
int i, j,s;
cout<<"Enter the sides of polygon :\n";
cin>>s;
cout<<"Enter the coordinates of polygon :\n";
cout<<"Enter x coordinates ";
for(i=0; i<s; i++)
cin>>mat[0][i];
cout<<"Enter y coordinates ";
for(i=0; i<s; i++)
cin>>mat[1][i];
cout<<"\n\n";
for(i=0; i<s; i++)
mat[2][i] = 1;
cout<<"MAt: "<<endl;
for(i=0; i<3; i++)
{
for(j=0; j<s; j++)
{
cout<<mat[i][j]<<" ";
}
cout<<endl;
}
multiply_matrix(reflect, mat);
cout<<"End"<<endl;
return 0;
}
I have attached a sample output image for reference:
Output of code
I am a newbie and have tried various things but I am just not able to figure my mistake. Thanks in advance for your help.
You have two s in your code. Globally:
int i , j,k,s;
And in main:
int i, j,s;
The one in main you assign a value read from user input, but the global one is 0 always. multiply_matrix uses the global one, hence this loops have zero iterations:
for (j = 0; j < s; j++)
{
result[i][j] = 0;
for (k = 0; k < 3; k++)
{
result[i][j]=result[i][j]+(A[i][k]*B[k][j]) ;
}
cout<<result[i][j]<<" ";//------(1)
}
and
for(j=0; j<s; j++)
{
cout<<result[i][j]<<" ";//------(B)
}
for my bucket sort, I don't know why the out put is segmentation fault: 11 when I try to print out sorted distance. It should be running well on win pc, but I try running it on mac, but i just get error. where am I wrong?
using namespace std;
void bucketSort(vector<double> &arr, int n)
{
vector<double> distance;
vector<double> b[n];
for (int i=1; i<=n/2; i++)
{
double c = sqrt(i)/sqrt(n/2);
cout<<c<<endl;
}
for (int i=0; i<n; i++)
{
double dist = sqrt(pow((arr[i]-0), 2) + pow((arr[i+1]-0), 2));
i = i+1;
distance.push_back(dist);
}
for (int i=0; i<n; i++)
{
int bi = n*distance[i]; // Index in bucket
b[bi].push_back(distance[i]);
}
for (int i=0; i<n; i++)
{
sort(b[i].begin(), b[i].end());
}
int index = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < b[i].size(); j++)
{
distance[index++] = b[i][j];
}
}
for (int i = 0; i < n/2; i++)
{
cout<<distance[i]<<endl;
}
}
int main()
{
vector<double> A;
double numbers;
while (cin>>numbers)
{
A.push_back(numbers);
}
int n = A.size();
bucketSort(A, n);
}
Here is the out put:
Claudes-MBP:desktop BengDai$ ./a.out < n.txt
0.5
0.707107
0.866025
1
Segmentation fault: 11
Claudes-MBP:desktop BengDai$
In your code you use arr[i+1] in a loop where is in the range 0 to n-1.
This means you will try and use arr[n] which is beyond the end of the array.
This block is also suspect:
for (int i=0; i<n; i++)
{
int bi = n*distance[i]; // Index in bucket
b[bi].push_back(distance[i]);
}
b[bi]: The value of bi could be bigger than the array size of b and probably is?
I just finished the bucket sort, it works fine without a for function:
for (int i=1; i<=n; i++)
{
double c = sqrt(i)/sqrt(n);
b[i]=c;
cout<<c<<endl;
}
but what I wan to do with this function is try to find the radii and set to the bucket. How what should I edit for it? Thanks for your view. Here is the whole code:
void bucketSort(vector<double> &arr, int n)
{
// 1) Create n empty buckets
vector<double> b[n];
//fnid the ring and set bucket
for (int i=1; i<=n; i++)
{
double c = sqrt(i)/sqrt(n);
b[i]=c;
cout<<c<<endl;
}
// 2) Put array elements in different buckets
for (int i=0; i<n; i++)
{
int bi = n*arr[i]; // Index in bucket
b[bi].push_back(arr[i]);
}
// 3) Sort individual buckets
for (int i=0; i<n; i++)
{
sort(b[i].begin(), b[i].end());
}
// 4) Concatenate all buckets into arr[]
int index = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < b[i].size(); j++)
{
arr[index++] = b[i][j];
}
}
}
/* Driver program to test above funtion */
int main()
{
vector<double> A;
double numbers;
while (cin>>numbers)
{
A.push_back(numbers);
}
int n = A.size();
bucketSort(A, n);
cout<<"Sort numbers: "<<endl;
for (int i=0; i<n; i++)
{
cout<<A[i]<<" ";
}
}
Here is the out put:
bucketSort_2.cpp:19:6: error: no match for 'operator=' (operand types are 'std::vector<double>' and 'double')
b[i]=c;
^
I am aware that there allready are similar questions here but no answer really helped me.
This is my problem:
I have given an array with 512x512 pixels in it. Each pixel has a value like 165.88009. ( I have to create a heatmap in GnuPlot later)
Now I want to "smoothen" it by creating the average of a variable block of pixels (like 4-16) and write it into a new 2D array and jump to the next block until it is done.
The size of the array should stay the same. So if I average 4 pixels those 4 pixels get the new value.
I made a function for this but it doesn't work properly.
Calculating the average is not my problem. The problem is that I want to have a variable width of pixels but I don't know how to make my algorithm jump to the next block.
Im not experienced in C++ and maybe I have to do it completely different.
So any help or inspiration is greatly appreciated :)
here is my code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int i, j, m, n, k;
void Average(double **Data, int width) // width gets defined and initiated in main
{
double sum;
double avg;
fstream Output;
Output.open( "GemittelteWerte.dat", ios::out);
double** IV_Matrix = new double* [m];
for (int i=0; i<m; i++)
{
IV_Matrix[i] = new double [n];
}
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
{
IV_Matrix[i][j] = 1.0;
}
}
// Here start all my troubles:
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j+=width)
{
sum = 0.0;
k=j;
for( k; k<(j+width); k++)
{
sum+=Data[i][k];
}
avg=(sum/width);
for (int k; k<(j+width); k++)
{
IV_Matrix[i][k] = avg;
}
}
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
Output<<setprecision(10)<<IV_Matrix[i][j]<<"\t";
}
Output<<"\n";
}
Output.close();
}
Is this block a 2D block (4 = 2x2, 16 = 4x4)? You simply want to do a 2D convolution? Then better use odd widths with 3x3, 5x5, ... kernels.
// int x, y are the dimensions of your image
double get (double **img, int i, int j) // zero padding for areas outside image
{
if (i<0 || i>=x || j<0 || j>=y)
return 0;
else
return img[i][j];
}
void conv (double **img, double **result, int width2) // kernel is (2*width2+1)^2
{
double sum;
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
{
sum = 0;
for (int ii=-width2; ii<=width2; ii++)
for (int jj=-width2; jj<=width2; jj++)
sum += get(img,i+ii,j+jj) / ((2*width2+1)*(2*width2+1));
result[i][j] = sum;
}
}
This smoothes img to result. Its however the slow unseparated solution. For small images and kernels no problem.
Edit: then easier:
// x, y are the dimensions of your image (x rows, y colums)
void avg (double **img, double **result, int width) // width must be >= 1 and
{ // should be a divider of y
double sum;
for (int i=0; i<x; i++) // process all rows
{
for (int j=0; j<y; j+=width) // jump in block width through a row
{
sum = 0.0;
for (int w=0; w<width; w++) // calculate average of a block
{
sum += img[i][j+w] / width;
}
for (int b=0; b<width; b++) // write average in each pixel inside block
{
result[i][j+b]= sum;
}
}
}
//di means diagonal index
for(int di = 0; di < n/width; ++di) {
int sum = 0.0;
//we sum the values
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = di*width; i < (di+1)*width; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
IV_Matrix[i][j];
}
}
}
//n might not be a multiple of width
if(n % width != 0) {
//we sum the values
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = di*width; j < (di+1)*width; ++j)
{
sum += Data[i][j];
}
}
//Divide by the number of values
sum /= width*width;
//Spread the results
for(int i = (n/width)*width; i < n; ++i)
{
for(int j = (n/width)*width; j < n; ++j)
IV_Matrix[i][j];
}
}
}