Matrix multiplication w/ random values wrong output - c++

I have written a program that gives random values to two matrices and then using multiplication to print out a third matrix. Matrix 1 is 3x3 (rows, columns) and Matrix 2 is (3x2).
My output is as follows:
Matrix 1:
4 6 0
9 1 5
4 7 5
Matrix 2:
4 6
0 9
1 5
matrix 1 x matrix 2:
16 78 97059710
41 88 218384285
21 112 97059715
As you can see the third matrix gives an extra row / column with weird values. (97057910 etc.)
Below is my multiply function written in C++:
Matrix Matrix::multiply(Matrix one, Matrix two) {
int n1 = one.data[0].size();
int n2 = two.data.size();
int nCommon = one.data.size();
vector< vector<int> > temp(nCommon);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);
for(int i=0;i<n1;i++) {
for(int j=0;j<n2;j++) {
for(int k=0;k<nCommon;k++) {
temp[i][j]= temp[i][j] + one.data[i][k] * two.data[k][j];
}
}
}
const Matrix result = Matrix(temp);
return result;
}
Does anyone have any suggestion on how to fix this issue? I want to remove that line of weird values and only have two columns.

You're getting your numbers of rows and columns mixed up. The idea is to multiply A (I x K) by B (K x J), and here's what the code does:
int n1 = one.data[0].size(); // this is K
int n2 = two.data.size(); // this is also K
int nCommon = one.data.size(); // this is I
vector< vector<int> > temp(nCommon);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);
// temp is now I x K, which is not what was intended,
// and the iteration over rows and columns will not be correct.
Try this instead:
int n1 = one.data.size(); // this is I
int n2 = two.data[0].size(); // this is J
int nCommon = two.data.size(); // this is K
vector< vector<int> > temp(n1);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);

Even though one of your matrixes has only two columns, looks like your for-loop will still attempt to access values in the third column of each row.
two.data[k][j]
k iterates from 0 to one.data.size()-1, or 0..2.
j also iterates from 0 to two.data.size()-1, also 0..2.
However, according to your description, the two's matrix's second dimension's range is only 0..1.
Undefined behavior. The code is running off past the end of the vector, and reads garbage.

Related

Eigen - Create sparse matrix with the elements of a vector on the kth diagonal

In Eigen the asDiagonal function creates a diagonal matrix using a vector.
This function only places the elements of the vector on the main diagonal.
Is there a fast way to create a sparse matrix with the elements of the vector on the kth diagonal?
For exemple for dense matrices, using positive index for diagonals above the main one and negative index for the ones below, I expected:
Vector3i(2,5,6).asDiagonal(-1);
To produce:
0 0 0 0
2 0 0 0
0 5 0 0
0 0 6 0
But asDiagonal takes no argument.
I know a way to do what I want, assuming that n is the length of the vector vect and d the diagonal index:
MartixXd m(n+abs(d),n+abs(d));
for (unsigned int i = 0; i < n; ++i)
m.diagonal(d)[i] = vect(i);
But unfortunately it doesn't work for sparse matrices...
So I ended up with this:
SparseMatrix<double> m(n+abs(d),n+abs(d));
m.reserve(n);
if (d < 0)
{
for (unsigned int l = 0; l < n; l++)
m.coeffRef(l-d,l) = vect.coeffRef(l);
} else {
for (unsigned int l = 0; l < n; l++)
m.coeffRef(l,l+d) = vect.coeffRef(l);
}
Is there a faster and/or more elegant way to do it?

Sum of values at common indexes in all subsets?

In a recent problem where i have to sum all values at common indexes in all possible subsets of size k in array of size n.
For eg: If
array ={1,2,3}
Its subsets (k=2) will be (x [i] , x [j]) where i < j
1 2
1 3
2 3
Sum:4,8
Firstly I have used recursion (same that of generating all subsets)
int sum_index[k]={0};
void sub_set(int array[],int n,int k,int temp[],int q=0,int r=0)
{
if(q==k)
{
for(int i=0;i<k;i++)
sum_index[i]+=temp[i];
}
else
{
for(int i=r;i<n;i++)
{
temp[q]=array[i];
sub_set(value,n,k,temp,q+1,i+1);
}
}
}
Problem is its taking too much time then expected .
Then i modified it to...
void sub_set(int array[],int n,int k,int temp[],int q=0,int r=0)
{
if(q==k)
{
return;
}
else
{
for(int i=r;i<n;i++)
{
temp[q]=array[i];
sum_index[q]+=temp[q]; //or sum_index[q]+=s[i];
sub_set(value,n,k,temp,q+1,i+1);
}
}
}
Still taking too much time!!
Is there any other approach to this problem?? Or any other modification i needed that i am unaware of??
Instead of iterating through the possible sub-sets, think of it a combinatorics problem.
To use your example of k=2 and {1,2,3}, let's just look at the first value of the result. It has two 1's and one 2. The two 1's correspond to the number one element sets that can be made from {2, 3} and the one 2 corresponds to the number of one element sets that can be made from {3}. A similar arrangement exists for the one 2 and two 3's in the second element of the result and looking at the subsets of the elements that appear before the element being considered.
Things get a bit more complicated when k>2 because then you will have to look for the number of combinations of elements before and after the element being considered, but the basic premise still works. Multiply the number of possible subsets before times the number of subsets afterwards and that will tell you how many times each element contributes to the result.
A solution in O(n^2) instead of O(n!):
First a tiny (:)) bit of explanation, then some code:
I´m going to assume here that your array is sorted (if not, use std::sort first). Additionally, I´m going to work with the array values 1,2,3,4... here, if you array consists arbitrary values (like 2 8 17), you´ll have to think of it as the indices (ie. 1=>2, 2=>8 etc.)
Definition: (x choose y) means the binomial coefficient, how it is calculated is in the link too. If you have an array size a and some k for the subset size, (a choose k) is the number of permutations, eg. 3 for your example: (1,2), (1,3) and (2,3).
You want the sum for each column if you write the permutations under each other, this would be easy if you knew for each column how many times each array element occurs, ie. how many 1´s, 2´s and 3´s for the first, and how many for second column (with k=2).
Here a bigger example to explain: (1,2,3,4,5) and all possible k´s (each in one block):
1
2
3
4
5
12
13
14
15
23
24
25
34
35
45
123
124
125
134
135
145
234
235
245
345
... (didn´t write k=4)
12345
Let´s introduce column indices, 0<=c<k, ie. c=0 means the first column, c=1 the second and so on; and the array size s=5.
So, looking eg. at the k=3-block, you´ll notice that the lines beginning with 1 (column c=0) have all permutations of the values (2,3,4,5) for k=2, more generally a value x in column c has all permutations for values x+1 to s after it. The values from from x+1 to s are s-x different values, and after column c there are k-c-1 more columns. So, for a value x, you can calculate ((s-x) choose (k-c-1)).
Additionally, the first column has only the values 1,2,3, the last two numbers are not here because after this column there are two more columns.
If you do this for the first column, it works well. Eg. with value 1 in the first column of k=3 above:
count(x) = ((s-x) choose (k-c-1)) = (4 choose 2) = 6
and indeed there are six 1 there. Calculate this count for every array value, multiply x*count(x), and sum it up for every x, that´s the result for the first column.
The other columns are a tiny bit harder, because there can be multiple "permutation blocks" of the same number. To start with, the step above needs a small adjustment: You need a muliplier array somewhere, one multiplier for each array value, and in the beginning each multiplier is 1. In the calculation x*count(x) above, take x*count(x)*muliplier(x) instead.
In the k=3-example, 1 in the first column can be followed by 2,3,4, 2 can be followed by 3,4, and 3 by 4. So the 3-based permutations of the second column need to be counted twice, and the 4-based even three times; more generally so many times like there are smaller values in the previos colums. Multiply that to the current multiplier.
...
Some code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
// factorial (x!)
unsigned long long fact(unsigned char x)
{
unsigned long long res = 1;
while(x)
{
res *= x;
x--;
}
return res;
}
//binomial coefficient (n choose k)
unsigned long long binom(unsigned char n, unsigned char k)
{
if(!n || !k) return 1;
return (fact(n) / fact(k)) / fact(n-k);
}
//just for convenience
template<class T> void printvector(std::vector<T> data)
{
for(auto l : data) cout << l << " ";
cout << endl;
}
std::vector<unsigned long long> calculate(std::vector<int> data, int k)
{
std::vector<unsigned long long> res(k, 0); //result data
std::vector<unsigned long long> multiplier(data.size(), 1);
if(k < 1 || k > 255 || data.size() < 1) return res; //invalid stuff
std::sort(data.begin(), data.end()); //as described
for(int column = 0; column < k; column++) //each column separately
{
//count what to multiply to the multiplier array later
std::vector<unsigned long long> newmultiplier(data.size(), 0);
//for each array element in this column
for(int x = column; x <= (data.size() + column - k); x++)
{
//core calculation
res[column] += data[x] * multiplier[x] * binom(data.size() - x - 1, k - column - 1);
//counting the new multiplier factor
for(int helper = x + 1; helper < data.size(); helper++)
newmultiplier[helper]++;
}
//calculating new multiplier
for(int x = 0; x < data.size(); x++)
{
if(newmultiplier[x])
multiplier[x] *= newmultiplier[x];
}
}
return res;
}
int main() {
printvector(calculate({1,2,3}, 2)); //output 4 8
return 0;
}
std::next_permutation may help:
std::vector<int> sub_set(const std::vector<int>& a, int k)
{
std::vector<int> res(k, 0);
std::vector<bool> p(a.size() - k, false);
p.resize(a.size(), true);
do
{
int index = 0;
for (std::size_t i = 0; i != p.size(); ++i) {
if (p[i]) {
res[index++] += a[i];
}
}
} while (std::next_permutation(p.begin(), p.end()));
return res;
}
Live Demo

Switching Matrix columns and rows in C++

I have a 6 x 6 matrix, and I am storing its values in a one dimensional array of size 36. I want to rearrange it so that the rows are the columns and the columns are the rows. My method is trying to copy the values into another array, but sorted properly. I am trying a for loop:
for (int i = 0; i < 6; ++i){
copyArray[i]= array[i*6];
}
This works fine for the first new row made up of the first column, but how do I continue to do all of them? I have tried nested for loops but cannot come up with the proper algorithm using iterators. I could do this manually, but would like to have this done by code.
I am coding in C++, but if anyone can do it in a similar language that would be fine. I feel this is a math problem.
The Question: How do I solve for switching out the rows and columns?
(Example: if I am denoting the first rows and columns as 0, in a 6x6 matrix, then both rows and columns go from 0 to 5. Therefore, by switching rows and columns, the value in row 2, column 5 would be switched with the value in row 5, column 2.)
Couldn't you just use a nested for loop and do something like this?
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyArray[i*6+j]= array[j*6+i];
Here's a test program you can run to show it works:
#include <stdio.h>
int main()
{
int array[36] = {1,1,1,1,1,1,
2,2,2,2,2,2,
3,3,3,3,3,3,
4,4,4,4,4,4,
5,5,5,5,5,5,
6,6,6,6,6,6};
int copyarray[36];
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyarray[i*6+j]= array[j*6+i];
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", array[i]);
}
printf("\n");
printf("\n");
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", copyarray[i]);
}
return 0;
}
Output:
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
You should keep your one-D array inside a class.
Then you can swap the dimensionality of the data without actually moving it.
class MySwapableArray
{
bool normal;
int array[36];
public:
int& operator()(int x, int y)
{
int h = normal ? x : y;
int v = normal ? y : x;
return array[h*6+v];
}
void swapRowsAndColumns()
{
normal = ! normal;
}
};
If you want to use operator[] like A[x][y] then see: How to overload array index operator for wrapper class of 2D array?
A template for doing so.
template<class X> std::unique_ptr<typename std::pointer_traits<X>::element_type[]>
transpose(const X& p, int x, int y) {
using T = std::pointer_traits<X>::element_type;
std::unique_ptr<T[]> r = new T[x*y];
for(int a = 0; a < x; ++a)
for(int b = 0; b < y; ++b)
r[x*a+b] = p[y*b+a];
return r;
}
If you want to avoid a double-for loop, you should be able to do it mathematically with something like
for (int i = 0; i < 36; ++i) {
copyarray[6 * (i % 6) + i / 6] = array[i]
}
Basically, 6 * (i % 6) aligns you to the right row in the transposed matrix, and the i / 6 (ab)uses integer division to translate the column value into a row value. floor (i / 6.0) is more correct if you can live with the clutter.
for( int i=0;i<6;i++)
for( int j=0;j<6;j++)
{ }//You can do whatever you want on original matrix here
Let's say that you want "transpose of matrix" and do some processing .Basically switch i and j
for( int j=0;j<6;j++) // replaceed i with j
for( int i=0;i<6;i++)
{ }//You can do whatever you want on transpose matrix here

In a matrix put 0 in the row and column of a cell which contains 0 without using extra space

Given a matrix, if a cell contains 0, then we have make entire row and column corresponding to the cell as 0. For example, if
1 2 3
M = 0 4 5
4 2 0
then the output should be
0 2 0
0 0 0
0 0 0
The method I thought is as follows
Make auxiliary arrays row[] and col[]. If a cell(i,j) contains 0 then, mark row[i] and col[j] as 0.(Initially row[] and col[] contains all 1s).
Again traverse the whole matrix, if for cell(i,j), either of row[i] or col[j] is 0, then put cell(i,j) as 0.
This takes O(m*n) time and O(m+n) space.
How to optimize it further specially in terms of space.Any suggestions for improving time complexity are also welcomed.
Aha, this is an old question.
Use one boolean variate(isZeroInFirstRow) saving if first row has zero element(s) or not and one boolean variate(isZeroInFirstCol) saving if first column has zero element(s) or not.
Then, traverse the whole matrix. If cell(i,j)==0, then set cell(0,j) and cell(i,0) to 0.
Traverse the first row of the matrix. If cell(0,j)==0, then set all elements in column(j) to 0.
Traverse the first column of the matrix. If cell(i,0)==0, then set all elements in row(i) to 0.
If isZeroInFirstRow==true, set all elements in row(0) to 0.
If isZeroInFirstCol==true, set all elements in column(0) to 0.
You can solve this in O(1) space. One solution is to iterate on the matrix, for each 0 you see, you fill the corresponding row/col with some character, 'X' for example.
When you finish, you should have something like that:
X 2 X
M= 0 X X
X X 0
Then you iterate again on the matrix and replace each 'X' with 0 to get:
0 2 0
M= 0 0 0
0 0 0
If you are concerned with storage you may think of using some sparse matrix storage formats to store the resulting matrix, and then free the original dense input.
An example of what I am proposing may be the following (implementing COO format) which should take O(M*N) time:
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstddef>
using namespace std;
int main()
{
constexpr size_t M = 3;
constexpr size_t N = 3;
int matrix[M][N] = {
{1, 2, 3},
{0, 4, 5},
{4, 2, 0}
};
vector<size_t> markedRows;
vector<size_t> markedColumns;
// Search for zeroes
for (size_t ii = 0; ii < M; ++ii) {
for(size_t jj = 0; jj < N; ++jj) {
if (matrix[ii][jj] == 0) {
markedRows.push_back (ii);
markedColumns.push_back(jj);
}
}
}
// Sort columns (rows are ordered by construction)
sort(markedColumns.begin(),markedColumns.end());
// Eliminate duplicates
markedRows.erase (unique(markedRows.begin() ,markedRows.end()) ,markedRows.end() );
markedColumns.erase(unique(markedColumns.begin(),markedColumns.end()),markedColumns.end());
// Construct COO matrix format
vector<size_t> irow;
vector<size_t> icol;
vector<int> val;
for (size_t ii = 0; ii < M; ++ii) {
for(size_t jj = 0; jj < N; ++jj) {
if ( ( find(markedRows.begin() ,markedRows.end() ,ii) == markedRows.end() ) &&
( find(markedColumns.begin(),markedColumns.end(),jj) == markedColumns.end() )
) {
irow.push_back(ii);
icol.push_back(jj);
val.push_back (matrix[ii][jj]);
}
}
}
// FROM HERE YOU NO LONGER NEED MATRIX, AND YOU CAN FREE THE STORAGE
// Print non zero entries
for( size_t ii = 0; ii < irow.size(); ++ii) {
cout << "A["<<irow[ii]<<","<<icol[ii]<<"] = "<<val[ii]<<endl;
}
return 0;
}
You can use your algorithm without allocating and auxiliary row or column by searching the matirx for a row that contains no zeros and a column that contains no zero elements.
If either of these searches fails, then the resulting matrix will all zeros, so your work is done by simply setting all elements to zero.
Otherwise, use the row and colum you found as the bookkeeping row and column you mentioned, setting the corresponding element to zero as you find zeros in the remainder of the matrix. Once that pass is done you walk the bookkeeping row, setting the matix columns to zeros for any zero found in the bookkeeping row, similarly for the aux column.
Here is an algorithm can do it in O(M*N) time and O(1) space : -
Find the max element in the matrix .
Mat[i][j] = max - Mat[i][j] for all (i,j)
Notice that Mat[i][j] will only have positive values.
Use negetive values as sentinels and Mat[i][j] = max as zeros.
Retrieve original values as Mat[i][j] = max - Mat[i][j]
Simple and easy answer:
<2 nested loop> to search through all columns and rows you find any cell = 0 through all column and set it to zeros through all row and set it to zeros. let me know if it not clear to record video for it.
Int main()
{
//example matrix dimension rows(r=6) * columns (c=3)
int r = 6;
int c = 3;
int matrix[r][c];
for(int i=0; i<r; ++i){
for(int j=0 ; j < c ; ++j){
if(matrix[i][j] == 0){
for(int ii=0; ii<r; ++ii){
Matrix[ii][j] = 0 ;
}
for(int jj=0; jj<c; ++jj){
Matrix[i][jj] = 0 ;
}
}
}
}
}

Print a specific number on a weird table

I have a table which consists of nonnegative integers that are layed out in this manner: Each element in the table is the minimum value that does not appear to its left or above it. Here's an example of a 6x6 grid:
0 1 2 3 4 5
1 0 3 2 5 4
2 3 0 1 6 7
3 2 1 0 7 6
4 5 6 7 0 1
5 4 7 6 1 0
The first row and column begin with 0 1 2 3 4 5... In coordinates (x,x) is always a 0, as you can see. On each tile after that, you have to place the smallest positive number that doesn't already exist on the same row or column. Much like in a sudoku-puzzle: There cannot be a number twice on the same row and column.
Now I have to print the number in the given coordinates (y,x). For example [2, 5] = 5
I came up with a working solution, but it takes way too much memory and time, and I just know there's another way of doing this. My time limit is 1 second, and the coordinates I have to find the number at can go up to (1000000, 1000000).
Here's my code at the moment:
#include <iostream>
#include <vector>
int main()
{
int y, x, grid_size;
std::vector< std::vector<int> > grid;
std::cin >> y >> x; // input the coordinates we're looking for
grid.resize(y, std::vector<int>(x, 0)); // resize the vector and initialize every tile to 0
for(int i = 0; i < y; i++)
for(int j = 0; j < x; j++)
{
int num = 1;
if(i != j) { // to keep the zero-diagonal
for(int h = 0; h < y; h++)
for(int k = 0; k < x; k++) { // scan the current row and column
if(grid[h][j] == num || grid[i][k] == num) { // if we encounter the current num
num++; // on the same row or column, increment num
h = -1; // scan the same row and column again
break;
}
}
grid[i][j] = num; // assign the smallest number possible to the current tile
}
}
/*for(int i = 0; i < y; i++) { // print the grid
for(int j = 0; j < x; j++) // for debugging
std::cout << grid[i][j] << " "; // reasons
std::cout << std::endl;
}*/
std::cout << grid[y-1][x-1] << std::endl; // print the tile number at the requested coordinates
//system("pause");
return 0;
}
So what should I do? Is this easier than I think it is?
To summarize your question: You have a table where each element is the minimum nonnegative integer that does not appear to its left or above. You need to find the element at position (x,y).
The result is surprisingly simple: If x and y are 0-based, then the element at (x,y) is x XOR y. This matches the table you have posted. I have verified it experimentally for a 200x200 table.
The proof:
It's easy to see that the same number won't appear twice on the same row or column, because if x1^y = x2^y then necessarily x1=x2.
To see that x^y is minimal: Let a be a number smaller than x^y. Let i be the index (from the right) of the leftmost bit where a differs from x^y. The ith bit of a must be 0 and the ith bit of x^y must be 1.
Therefore, either x or y must have 0 in the ith bit. Suppose WLOG it was x that had 0. Represent x and y as:
x = A0B
y = C1D
Where A,B,C,D are sequences of bits, and B and D are i bits long. Since the leftmost bits of a are the same as those in x^y:
a^x = C0E
Where E is a sequence of i bits. So we can see that a^x < y. The value that appered in the (a^x)th row on the same column was: (a^x)^x = a. So the value a must have already appeared in the same row (or column, if it was y that had 0 in the ith bit). This is true for any value smaller than x^y, so x^y is indeed the minimum possible value.