Matrix multiplication - C++ [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
void power(int a[][21], int n, int d) {
int e[21][21], k, i, j, l;
if (d == 1) {
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
cout << a[i][j] << " ";
cout << endl;
}
} else {
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
e[i][j] = 0;
for (l = 1; l < d; l++)
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
for (k = 1; k <= n; k++)
e[i][j] = e[i][j] + (a[i][k] * a[k][j]);
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
cout << e[i][j] << " ";
cout << endl;
}
}
}
I am trying to build a function that calculates the power of a matrix. The program works for the 1st and 2nd power of the matrix but if I want to calculate the 3rd power the function will return incorrect values. I think the problem is at retaining the previous results but I can't figure out on how to fix it.

This block of code
for (l = 1; l < d; l++)
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
for (k = 1; k <= n; k++)
e[i][j] = e[i][j] + (a[i][k] * a[k][j]);
sets e to be a*a no matter what d is.
You need to have a temporary matrix to make things work.
Bootstrap:
e = a;
In the loop:
temp = e;
e = temp * a;
temp = e;
e = temp * a;
... etc.
Something along the lines of:
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
e[i][j] = a[i][j];
}
}
for (l = 1; l < d; l++)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
temp[i][j] = e[i][j];
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
e[i][j] = 0;
for (k = 0; k < n; k++)
{
e[i][j] += (temp[i][k] * a[k][j]);
}
}
}
}
PS I have used 0-based indexing to access the matrices. I am not sure why you have used 1-based indexing.

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.

Counting Sort in C++

I am trying to implement the Counting Sort in C++ without creating a function. This is the code that I've written so far, but the program doesn't return me any values. It doesn't give me any errors either. Therefore, what is wrong?
#include <iostream>
using namespace std;
int main()
{
int A[100], B[100], C[100], i, j, k = 0, n;
cin >> n;
for (i = 0; i < n; ++i)
{
cin >> A[i];
}
for (i = 0; i < n; ++i)
{
if (A[i] > k)
{
k = A[i];
}
}
for (i = 0; i < k + 1; ++i)
{
C[i] = 0;
}
for (j = 0; j < n; ++j)
{
C[A[j]]++;
}
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
for (i = 0; i < n; ++i)
{
cout << B[i] << " ";
}
return 0;
}
It looks like you're on the right track. You take input into A, find the largest value you'll be dealing with and then make sure you zero out that many values in your C array. But that's when things start to go wrong. You then do:
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
That first loop will always go out of bounds on the first iteration (C[i-1] when i=0 will be undefined behavior), but even if it didn't I'm not sure what you have in mind here. Or in the loop after that for that matter.
Instead, if I were you, I'd create an indx variable to keep track of which index I'm next going to insert a number to (how many numbers I've inserted so far), and then I'd loop over C and for each value in C, I'd loop that many times and insert that many values of that index. My explanation may sound a little wordy, but that'd look like:
int indx = 0;
for(int x = 0; x <= k; x++) {
for(int y = 0; y < C[x]; y++) {
B[indx++] = x;
}
}
If you replace the two loops above with this one, then everything should work as expected.
See a live example here: ideone

why this algorithm (Floyd Warshal algorithm) only works for 100000007?

This is Floyd Warshal algorithm which i'm using to find the maximum of minimum path in a graph. Why this algorithm don't work if i put INT_MAX or any other big integer like 2147483647 in place of 100000007.
int main() {
int c,f; //c=number of vertice
// f=number of pair of vertices directly connected
cin >> c >> f;
int graph[c][c];
for(int i = 0;i < c;i++)
for(int j = 0;j < c;j++)
graph[i][j] = 100000007;
for(int i = 0;i < c;i++)
graph[i][i] = 0;
int x,y,p;
for(int i = 0;i < f;i++) {
cin >> x >> y >> p;
graph[x-1][y-1] = p;
graph[y-1][x-1] = p;
}
int dist[c][c], i, j, k;
for(i = 0; i < c; i++)
for (j = 0; j < c; j++)
dist[i][j] = graph[i][j];
for(k = 0; k < c; k++) {
for(i = 0; i < c; i++) {
for(j = 0; j < c; j++) {
if(dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
int ans = 0;
for(int i = 0;i < c;i++)
for(int j = 0;j < c;j++)
ans = max(ans,dist[i][j]);
cout << ans << endl;
return 0;
}
(as in the comments)
Once your value for infinity is greater than INT_MAX / 2, which is 1,073,741,823, the line if(dist[i][k] + dist[k][j] < dist[i][j]) has an overflow in it. Overflow is undefined behavior in C++, but the most likely outcome is that dist[i][k] + dist[k][j] becomes a negative value, and in the next line, dist[i][j] = dist[i][k] + dist[k][j];, actual distances get overwritten by such negative values.
The value you need for infinity should be greater than any real distance you can encounter. If that distance exceeds 230 - 1, consider using a type with higher upper limit (unsigned int32, int64, or even a double).

dijkstra's algorithm using matrix in c++. what's wrong in this code?

#include <iostream>
int n, m, v1, v2, weight;
cin >> n >> m;
int** graph = new int*[n];
int* distance = new int[n];
int* s = new int[n];
for (int i = 0; i < n; ++i)
graph[i] = new int[n];
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
graph[i][j] = INT_MAX;
for (int i = 0; i < m; ++i)
{
cin >> v1 >> v2 >> weight;
graph[v1][v2] = weight;
graph[v2][v1] = weight;
}
for (int i = 0; i < n; ++i)
distance[i] = INT_MAX;
for (int i = 0; i < n; ++i)
distance[i] = graph[0][i];
for (int i = 0; i < n; ++i)
s[i] = 0;
distance[0] = 0;
int min = INT_MAX;
int vertex = 0;
for (int j = 0; j < n-1; ++j){
min = INT_MAX;
for (int i = 0; i < n; ++i)
if (s[i] == 0 && min >= distance[i])
{
vertex = i;
min = distance[i];
}
s[vertex] = 1;
cout << vertex << " ";
for (int i = 0; i < n; ++i)
if (distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
}
for (int i = 0; i < n; ++i)
cout << distance[i] << " ";
cout << endl;
return 0;
}
Hi. I'm making Dijkstra's algorithm using two-dimentional matrix..
but this code doesn't work. and i don't know why! Can you fix my problem??
i want to make output all distance of graph. but output is looks like array point garbage value like -2345...
Can you help me??
There are some problems in this loop:
for (int i = 0; i < n; ++i)
if (distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
should change to the blew code:
for (int i = 0; i < n; ++i)
if (s[i] == 0 && graph[vertex][i] != INT_MAX && distance[i]>distance[vertex] + graph[vertex][i])
distance[i] = distance[vertex] + graph[vertex][i];
because if the graph[vertex][i] == INT_MAX, the sum of distance[vertex] + graph[vertex][i] is overflow. Another problem is that the vertex i should not be marked before.

how to optimize a 'for loop' for 3d complex<double> arrays to improve speed in C++

all the arrays in this code are complex type in this code and the running time for this for loop is about 1 min. Ktemp is an array with size 141*1202*141. could anyone help me to optimize this code and save the running time?
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
my second question is about rewriting matlab function 'fftshift' with C++. I have finished the code, but it seems not that efficient. could anyone help me rewrite this code? my code is attached below:
complex<double> ***fftw_shift(complex<double> ***te, int a, int b, int c)
{
complex<double> ***tempa;
tempa = new complex<double> **[a];
for (i = 0; i < a; i++)
{
tempa[i] = new complex<double> *[b];
for (j = 0; j < b; j++)
{
tempa[i][j] = new complex<double>[c];
}
}
/*for the row*/
if (c % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2 + 1];
tempa[i][j][k + c / 2] = te[i][j][k];
tempa[i][j][c - 1] = te[i][j][c / 2];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c / 2; k++)
{
tempa[i][j][k] = te[i][j][k + c / 2];
tempa[i][j][k + c / 2] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the column*/
if (b % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2 + 1][k];
tempa[i][j + b / 2][k] = te[i][j][k];
tempa[i][b - 1][k] = te[i][b / 2][k];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b / 2; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + b / 2][k];
tempa[i][j + b / 2][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the third dimension*/
if (a % 2 == 1)
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2 + 1][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
tempa[a - 1][j][k] = te[a / 2][j][k];
}
}
}
}
else
{
for (i = 0; i < a / 2; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + a / 2][j][k];
tempa[i + a / 2][j][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
return (te);
}
Since you are repeatedly multiplying by the values in expn (i.e. calculating an exponent) you can do this more efficiently using the pow function and get rid of the zz loop:
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
excit_pfft[i][j][k] = 0;
}
else
{
excit_pfft[i][j][k] = excit_pfft[i][j][k] * pow(expn[i][j][k], 20);
}
}
}
}
Your code also seems to have a memory leak because you assign P1 to excit_pfft, but never free the previous contents of excit_pfft. You don't need to have the P1 temporary array in any case once you get rid of the outer loop.
I'm not sure of the internals of the complex pow() function, but you can calculate the (scalar) exponent of a complex number geometrically by converting it to polar co-ordinates (angle + distance scalar), then multiplying the angle by the power and raising the distance to the power, then converting back. So it's a lot faster than repeated multiplication.
First (will probably give you a big performance boost), get rid of the pointer arrays if you know beforehand the size of your arrays and simply allocate them in the stack:
complex<double> P1[141][1202][141];
Instead of :
complex<double> ***P1;
P1 = new complex<double>**[141];
for (i = 0; i < num_y; i++)
{
P1[i] = new complex<double> *[1202];
for (j = 0; j < tsize; j++)
{
P1[i][j] = new complex<double>[141];
}
}
And since I don't know exactly what this does, I'm assuming this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = excit_pfft[i][j][k] * expn[i][j][k];
}
}
}
}
excit_pfft = P1;
}
Could become this:
for (int zz = 1; zz < 20; zz++)//in z direction
{
for (i = 0; i < 141; i++)
{
for (j = 0; j < 1202; j++)
{
for (k = 0; k < 141; k++)
{
if (Ktemp[i][j][k].real() <= 0)
{
P1[i][j][k] = 0;
}
else
{
P1[i][j][k] = P1[i][j][k] * expn[i][j][k];
}
}
}
}
}
If this cannot be done than I'll need a more broad chunk of this code to analyze excit_pfft, etc.
A huge performance boost you could have is to use Worker Threads and run this last code multithreaded.
The same goes for our second question, Worker Threads should do it.
EDIT:
On second though, the stack won't be able to handle that much variables.
I'd recommend using vector<vector<vector<complex<double> > > > instead.