Eigen: Zero matrix with smaller matrix as the "diagonals" - c++

Is it possible to create a 9x9 matrix where the "diagonal" is another matrix and the rest are zeroes, like this:
5 5 5 0 0 0 0 0 0
5 5 5 0 0 0 0 0 0
5 5 5 0 0 0 0 0 0
0 0 0 5 5 5 0 0 0
0 0 0 5 5 5 0 0 0
0 0 0 5 5 5 0 0 0
0 0 0 0 0 0 5 5 5
0 0 0 0 0 0 5 5 5
0 0 0 0 0 0 5 5 5
from a smaller 3x3 matrix repeated:
5 5 5
5 5 5
5 5 5
I am aware of the Replicate function but that repeats it everywhere in the matrix and doesn't maintain the zeroes. Is there a builtin way of achieving what I'm after?

One way of doing this is by using blocks where .block<3,3>(0,0) is a 3x3 block starting at 0,0. (Note: Your IDE might flag this line as an error but it will compile and run)
for (int x=0, x<3, x++){
zero_matrix.block<3,3>(x*3,x*3) = five_matrix;
}

You can use the (unsupported) KroneckerProduct module for that:
#include <unsupported/Eigen/KroneckerProduct>
int main()
{
Eigen::MatrixXd A = Eigen::kroneckerProduct(Eigen::Matrix3d::Identity(), Eigen::Matrix3d::Constant(5));
std::cout << A << '\n';
}

Related

Retrieve multiple ArrayFire subarrays from min/max data points

I have an array with sections of touching values in it. For example:
0 0 1 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 2 2 0 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0
0 0 3 0 0 0 0 0 0 0
from this, I created a set of af::arrays: minX, maxX, minY, maxY. These define the box that encloses each group.
so for this example:
minX would be: [1,5,2] // 1 for label(1), 5 for label(2) and 2 for label(3)
maxX would be: [3,7,2] // 3 for label(1), 7 for label(2) and 2 for label(3)
minY would be: [0,3,7] // 0 for label(1), 3 for label(2) and 7 for label(3)
maxY would be: [1,4,9] // 1 for label(1), 4 for label(2) and 9 for label(3)
So if you take the i'th element from each of those arrays, you can get the upperleft/lowerright bounds of a box that encloses the corresponding label.
I would like use these values to pull out subarrays from this larger array. My goal is to put these values enclosed in the boxes into a flat list. In GPU memory, I also have calculated how many entries I would need for each box using the max/min X/Y values. So in this example - the result of the flat list should be:
result=[0 1 0 1 1 1 2 2 2 0 0 2 3 3 3]
where the first 6 entries are from the box
______
|0 1 0 |
|1 1 1 |
------
the second 6 entries are from the box
______
|2 2 2 |
|0 0 2 |
------
and the final three entries are from the box
___
| 3 |
| 3 |
| 3 |
---
I cannot figure out how to index into this af::array with min/max values in memory that resides on the GPU (and do not want to transfer them to the CPU). I was trying to see if gfor/seq would work for me, but it appears that af::seq cannot use array data, and everything I have tried with using af::index i could not get to work for me either.
I am able to change how I represent min/max (I could store indices for upper left/lower right) but my main goal is to do this efficiently on the GPU without moving data back and forth between the GPU and CPU.
How can this be achieved efficiently with ArrayFire?
Thank you for your help
How did you get there so far? which language are you using?
I guess you could be tiling the results to 3rd dimensions to handle each regions separately and end up with min/max vectors in GPU memory.

Extracting integers from file

I have the following file stored in a string vector.
ratingsTiny.txt...
Jesse
-3 5 -3 0 -1 -1 0 0 5
Shakea
5 0 5 0 5 0 0 0 1
Batool
5 -5 0 0 0 0 0 -3 -5
Muhammad
0 0 0 -5 0 -3 0 0 0
Maria
5 0 5 0 0 0 0 1 0
Alex
5 0 0 5 0 5 5 1 0
Riley
-5 3 -5 0 -1 0 0 0 3
My goal is extract the numbers, preferably column wise, to add them together and get an average rating for each column among the 7 users.
My closest attempt is below, but I can only print the first column and I can't figure out how to iterate through the entirety of the rows to get the rest of the integers.
Any help is very much appreciated.
ourvector<string> ratings;
for (int i = 1; i < ratings.size(); i += 2){
int num = atoi(ratings[i].c_str());
intRatings.push_back(num);
cout << num << endl;
}

How can I find the shortest path between specific items in a matrix?

I have to find the shortest path between a '1' element of the matrix and a '2' element crossing only throw the '0' elements. I first thought of using the Lee algorithm but it would take to much space given that the matrix can have up to 101 elements.
This is an example of an input
I already know the length of the matrix.
1 0 0 0 2 2 0
0 1 1 0 3 1 3
3 3 3 3 0 0 0
2 0 3 3 0 0 0
2 2 0 3 0 1 1
2 0 0 0 0 1 0
The output is 4 the shortest path being:
1 0 0 0 2 2 0
0 1 1 0 3 1 3
3 3 3 3 0 0 0
2 0 3 3 0 0 0
2 2 0 3 0 1 1
2 * * * * 1 0

parse collection of single integers into floats

So i slurped in a file with numbers in it like: 39.00 into a vector<std::string> and now I need to convert groups of numbers that look like 3 9 0 0 back into the form 39.00
heres a small sample.
3 4 5 0 1 2 5 0 3 4 0 0 3 4 9 0 7 0 0 0 8 0 0 0 9 0 0 0 6 5 0 0 3 9 3 2 1 1 2 0 0 0 2 5 0 0 3 0 9 0 4 0 0 0 5 5 5 0 2 0 0 0 2 5 0 0 3 0 9 0 4 0 0 0 5 5 5 0 2 2 3 0 0 0 2 4 0 0 4 5 0 0 6 7 0 0 6 5 5 0 5 6 9 0 8 7 0 0 4 3 5 0 5 6 9 8 5 5 4 0 3 3 6 2 0 0 3 4 5 0 1 2 5 0 3 4 0 0 3 4 9 0 7 0 0 0 8 0 0 0 9 0 0 0 6 5 0 0 3 9 0 3 2 1 1 2 0 0 0 2 5 0 0 3 0 9 0 4 0 0 0 5 5 5 0 2 0 0 0 2 5 0 0 3 0 9 0 4 0 0 0 5 5 5 0 2 2 3 0 0 0 2 4 0 0 4 5 0 0 6 7 0 0 6 5 5 0 5 6 9 0 8 7 0 0 4 3 5 0 5 6 9 8 5 5 4 0 3 3 6 2 0 0 3 4 5 0 1 2 5 0 3 4 0 0 3 4 9 0 7 0 0 0 8 0 0 0 9 0 0 0 6 5 0 0 3 9 0 0
transformed into 34.50 12.50 34.00....
My goal is to eventually find the average of all the floats.
Of course if there is a way to slurp a file while keeping formatting only using the standard library that would be cool too.
#include <iostream>
#include <string>
#include <fstream>
#include <streambuf>
#include <regex>
#include <vector>
#include <math.h>
void tableWriter(std::string);
float employeeAverage(std::string);
float employeeTotal(std::string);
float totalAverage(std::string);
void totalPayroll(std::string, std::vector<std::string>);
std::string getEmployeeName(std::string, std::string[]);
int main(int argc, const char * argv[]) {
try {
std::vector<std::string> regexContainer;
std::ifstream t("TheSales.txt");
std::string theSales;
t.seekg(0, std::ios::end);
theSales.reserve(t.tellg());
t.seekg(0, std::ios::beg);
theSales.assign((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
//std::cout << theSales << std::endl;
totalPayroll(theSales, regexContainer);
std::cout << std::endl << regexContainer.empty() << std::endl;
return 0;
} catch (int w) {
std::cout << "Could not open file. Exiting Now." << std::endl; return 0;
}
}
void tableWriter(std::string){}
float employeeAverage(std::string){return 0.0;}
float employeeTotal(std::string){return 0.0;}
float totalAverage(std::string){return 0.0;}
void totalPayroll(std::string theSales, std::vector<std::string> regexContainer) {
std::string matches;
std::regex pattern ("\\d");
const std::sregex_token_iterator end;
for (std::sregex_token_iterator i(theSales.cbegin(), theSales.cend(), pattern);
i != end;
++i)
{
regexContainer.push_back(*i);
for (std::vector<std::string>::const_iterator i = regexContainer.begin(); i != regexContainer.end(); ++i)
std::cout << *i << ' ';
}
}
this is the data:
2.40 5.30 6.30 65.34 65.34
3.40 7.80 3.20 65.34 65.34
3.40 5.20 8.20 23.54 12.34
2.42 5.30 6.30 5.00 65.34
3.44 7.80 3.20 34.55 65.34
3.45 5.20 8.20 65.34 65.34
Functions such as fscanf are able to read from your file and return a correctly formed float number. This should be more efficient than trying to reconstruct them from a stream of char...

Random function keeps on getting same result [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 7 years ago.
I am writing a program to simulate Knight's tour randomly. (See wikipedia for what it means: http://en.wikipedia.org/wiki/Knight%27s_tour) First, I create a chess object, which is basically just a 8*8 array with numbers to indicate the position of the knight. I create a chess object and randomly assign a position for the knight. Then, I moved the knight randomly until there is no more legal moves and returns the number of moves performed.
int runTour ()
{
srand (time(NULL));
Chess knight(rand()%8, rand()%8); //Initialize random chess object.
knight.printBoard(); //Prints the board before moving
int moveNumber = 0; //A number from 0 to 7 that dictates how the knight moves
int counter = 0;
while (moveNumber != -1) //A moveNumber of -1 means there is no more legal move
{
moveNumber = knight.findRandMove(knight.getRow(), knight.getColumn()); //findRandMove is a function that returns a legal random move for the knight based on its position. It works perfectly.
knight.move(moveNumber); //move is a function that moves the knight
counter ++;
}
knight.printBoard(); // Returns board when move is exhausted
return counter; //Returns number of moves performed.
}
The interesting thing is that while it runs perfectly randomly from run to run, it keeps outputting the same thing in the same run. For example, this is the main() function:
int main(){
runTour();
runTour();
return 0;
}
And in BOTH runTour() it outputs: (where 0 represents positions not reached, 1 represents the current position of the knight, and 9 positions reached)
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0
0 9 9 0 0 0 9 0
0 0 0 0 0 9 9 0
9 0 9 9 9 9 0 1
0 0 9 9 9 9 9 9
0 9 9 9 9 0 9 0
9 0 0 0 9 9 9 9
0 0 9 0 9 9 0 9
And when I run it again, BOTH runTour output:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 9 9
0 9 0 0 9 9 9 0
0 0 9 9 9 9 9 9
1 0 9 0 9 9 0 9
So the random function is random in different runs, but is the same in each run. Why is this the case? How can I modify the code so that runTour() can have different performances when it is called? Thank you very much for reading this clumsy question.
As you´re using a timestamp as srand seed:
If both runTours are in the same second, what do you think will happen with your code?
...
srand is supposed to be called exactly one time, not one time per function call of runTour
Try moving your srand call to your main function. You should only have to seed the generator one time, rather than each time you call the function.