I have about 1000 lines of code that I wrote in C for a linear programming solver (interior point algorithm). I realized that I need to use Eigen to calculate a matrix inverse, so now I am running my code in C++ instead (runs just fine, it seems). Now I have a bunch of arrays declared in C format, for example: A[30][30];
In my program, I do a bunch of matrix calculations and then need to find an inverse of a matrix at some point, let's call it matrix L[30][30]. To use Eigen, I need to have it in a special Eigen matrix format to call the function m.inverse like this:
//cout << "The inverse of L is:\n" << L.inverse() << endl;
My goal is to find a way... ANY way, to get my data from L to a format that Eigen will accept so I can run this thing. I've spent the last 2 hours researching this and have come up with nothing. :-( I'm fairly new to C, so please be as thorough as you can. I want the most simple method possible. I've read about mappings, but I'm not very clear on pointers sadly (which seems to be an integral part). Is there a way to just loop through each row and column and copy them into an Eigen matrix?
While I'm asking, will I need to take the resultant Eigen matrix and turn it back into a C array? How would that process work? Thanks in advance for any help! I've spent about 50-60 hours on this and it's due this week! This is the LAST thing I need to do and I'll be done with my term project. It's a math class, so the programming side of things are a little fuzzy for me but I'm learning a lot.
Possibly relevant information:
-Running on Windows 10 i7 processor Sony VAIO
-Compiling with CodeBlocks in C++, but originally written in C
-This code is all in a while loop that may be iterated through 10 times or so.
-The matrix inverse needs to be calculated for this matrix L each iteration, and the data will be different each time.
Please help! I'm willing to learn, but I need guidance and this class is online so I have virtually none. Thanks so much in advance!
Edit - I saw this and tried to implement it to no avail, but it seems like the solution if I can figure this out:
"Suppose you have an array with double values of size nRows x nCols.
double *X; // non-NULL pointer to some data
You can create an nRows x nCols size double matrix using the Map functionality like this:
MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
The Map operation maps the existing memory region into the Eigen’s data structures. A single line like this allows to avoid to write ugly code of matrix creation, for loop with copying each element in good order etc."
This seems to be a nice solution, but I am clueless on how to do anything with that "double *X" that says to "point to some data". I began looking up pointers and such and it didn't help clarify - I saw all kinds of things about pointing to multi-dimensional arrays that didn't seem to help.
I also don't quite understand the format of the second line. Is every capital X there just going to be the same as the matrix *X in the line before? What would I need to declare/create for that? Or is there an easier way that all of this?
EDIT2: Here is what I have in my program, essentially - this is significantly shrunken down, sorry if it's still too long.
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
typedef Matrix<double, 30, 30> Matrix30d;
double L[30][30] ={{0}};
double Ax[30][30] = {{0}}; //[A] times [x]
double At[30][30] = {{0}}; //A transpose
double ct[30][30] = {{0}}; //c transpose
double x[30][30] = {{0}}; //primal solution
double w[30][30] = {{0}}; //omega, dual solution
double s[30][30] = {{0}}; //dual slack
double u[30][30] = {{0}}; //[c]t - [A]t x [w] - [s]
double Atxw[30][30] = {{0}}; //A transpose times omega
double t[30][30] = {{0}}; //RHS - [A]x[x]
double v[30][30] = {{0}}; //mu - xij * sij
double p[30][30] = {{0}}; //vij / xij
double D2[30][30] = {{0}}; //diagonal of xij/sij
double AD2[30][30] = {{0}}; //[A] x [D2]
double AD2xAt[30][30] = {{0}}; //[AD2] x [At]
double uminp[30][30] = {{0}}; //[u] - [p]
double AD2xuminp[30][30] = {{0}}; //[AD2] x [uminp]
double z[30][30] = {{0}}; //[AD2] x [uminp] + [t]
double Atxdw[30][30] = {{0}}; //[At] x [dw]
double xt[30][30] = {{0}}; //x transpose
double bt[30][30] = {{0}}; //b transpose
Matrix30d Inv; //C++ style matrix for Eigen, maybe needed?
int main(){
int r1; //rows of A
int c1; //columns of A
int i; //row and column counters
int j;
int k;
double sum = 0;
double size; //size of square matrix being inverted [L]
double *pointer[30][30];
FILE *myLPproblem;
myLPproblem = fopen("LPproblem.txt", "r"); //Opens file and reads in data
float firstLine[4];
int Anz;
for (i = 0; i < 4; i++)
{
fscanf(myLPproblem, "%f", &firstLine[i]);
}
r1 = firstLine[0];
c1 = firstLine[1];
Anz = firstLine[2];
double A[r1][c1];
double b[r1][1];
double c[1][c1];
int Ap[c1+1];
int Ai[Anz];
double Ax2[Anz];
for(i=0; i<r1; i++){
for(j=0; j<c1; j++){
A[i][j]=0;
}
}
for (i = 0; i < (c1 + 1); i++)
{
fscanf(myLPproblem, "%d", &Ap[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%d", &Ai[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%lf", &Ax2[i]);
}
for (i = 0; i < (r1); i++)
{
fscanf(myLPproblem, "%lf", &b[i][0]);
}
for (i = 0; i < (c1); i++)
{
fscanf(myLPproblem, "%lf", &c[0][i]);
}
fclose(myLPproblem);
int row;
double xval;
int Apj;
int Apj2;
for(j=0; j<c1; j++){
Apj = Ap[j];
Apj2 = Ap[j+1];
for(i=Apj; i<Apj2; i++){
row = Ai[i];
xval = Ax2[i];
A[row][j] = xval;
}
}
size = r1;
for(i=0; i<c1; i++) //Create c transpose
{
ct[i][0] = c[0][i];
}
for(i=0; i<r1; i++) //Create b transpose
{
bt[i][0] = b[0][i];
}
for(i=0; i<c1; i++) //Create A transpose
{
for(j=0; j<r1; j++)
{
At[i][j] = A[j][i];
}
}
while(1){ //Main loop for iterations
for (i = 0; i <= r1; i++) { //Multiply [A] times [x]
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * x[k][j];
}
Ax[i][j] = sum;
}
}
sum = 0; //Multiply [At] times [w]
for (i = 0; i <= c1; i++){
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= r1; k++) {
sum = sum + At[i][k] * w[k][j];
}
Atxw[i][j] = sum;
}
}
for(i=0; i<c1; i++) //Subtraction to create matrix u
{for(j=0; j<1; j++)
{
u[i][j] = (ct[i][j]) - (Atxw[i][j]) - (s[i][j]);
}
}
for(i=0; i<r1; i++) //Subtraction to create matrix t
{for(j=0; j<1; j++)
{
t[i][j] = (b[i][j]) - (Ax[i][j]);
}
}
for(i=0; i<c1; i++) //Subtract and multiply to make matrix v
{for(j=0; j<1; j++)
{
v[i][j] = mu - x[i][j]*s[i][j];
}
}
for(i=0; i<c1; i++) //create matrix p
{for(j=0; j<1; j++)
{
p[i][j] = v[i][j] / x[i][j];
}
}
for(i=0; i<c1; i++) //create matrix D2
{for(j=0; j<c1; j++)
{
if(i == j){
D2[i][j] = x[i][0] / s[i][0];
}else{
D2[i][j] = 0;
}
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [A] times [D2]
for (j = 0; j <= c1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * D2[k][j];
}
AD2[i][j] = sum;
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [AD2] times [At], to be inverted!
for (j = 0; j <= r1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + AD2[i][k] * At[k][j];
}
AD2xAt[i][j] = sum;
}
}
//Here is where I need to calculate the inverse (and determinant probably) of matrix AD2xAt. I'd like to inverse to then be stored as [L].
//cout << "The determinant of AD2xAt is " << AD2xAt.determinant() << endl;
//cout << "The inverse of AD2xAt is:\n" << AD2xAt.inverse() << endl;
printf("\n\nThe inverse of AD2xAt, L, is : \n\n"); //print matrix L
for (i=0; i<size; i++)
{
for (j=0; j<size; j++)
{
printf("%.3f\t",AD2xAt[i][j]);
}
printf("\n");
}
}
return 0;
}
In a nutshell, it reads matrices from a file, calculates a bunch of matrices, then needs to invert AD2xAt and store it as L. The critical part is at the end, where I need to take the inverse (scroll to the bottom - I have it commented).
Have you tried
Map<MatrixXd>(A[0],30,30).inverse() ??
– ggael
What you're proposing seems like it would be doing both at once or
something?
Right, the Map<MatrixXd>() returns the Eigen's MatrixXd, on which the method inverse() is called.
May I ask what the [0] is after A?
[0] is the array subscript operator [] designating the 0-th element; A[0] is the initial row of the matrix A[30][30] and is converted to the pointer to A[0][0] corresponding to the X you saw.
Related
Given an m x n integer grid, return the size (i.e., the side length k) of the largest magic square that can be found within this grid.
The question can be found here on leetcode
I first wanted to see if a naive brute force approach would pass, so I came up with the following algorithm
Iterate through all values of k (from min(rows,cols) of the matrix to 1)
For each of the k values, check if it's possible to create a magic of square of dimensions kxk by checking all possible sub matrices and
return k if it's possible. This would be O(rows*cols*k^2)
So that would make the overall complexity O(k^3*rows*cols). (Please correct me if I am wrong)
I have attached my code in C++ below
class Solution {
public:
int largestMagicSquare(vector<vector<int>>& grid) {
int rows = grid.size(),cols = grid[0].size();
for(int k = min(rows,cols); k >= 2; k--){ // iterate over all values of k
for(int i = 0; i < rows-k+1; i++){
for(int j = 0; j < cols-k+1; j++){
int startX = i, startY = j, endX = i+k-1, endY = j+k-1;
int diagSum = 0, antiDiagSum = 0;
bool valid = true;
// calculate sum of diag
for(int count = 0; count < k; count++){
diagSum += grid[startX][startY];
startX++,startY++;
}
// this is the sum that must be same across all rows, cols, diag and antidiag
int sum = diagSum;
// calculate sum of antidiag
for(int count = 0; count < k; count++){
antiDiagSum += grid[endX][endY];
endX--,endY--;
}
if(antiDiagSum != sum) continue;
// calculate sum across cols
for(int r = i; r <=i+k-1; r++){
int colSum = 0;
for(int c = j; c <= j+k-1; c++){
colSum += grid[r][c];
}
if(colSum != sum){
valid = false;
break;
}
}
if(!valid) continue;
// calculate sum across rows
for(int c = j; c <= j+k-1; c++){
int rowSum = 0;
for(int r = i; r <= i+k-1; r++){
rowSum += grid[r][c];
}
if(rowSum != sum){
valid = false;
break;
}
}
if(!valid) continue;
return k;
}
}
}
return 1;
}
};
I thought I would optimize the solution once this works (Maybe binary search over the values of k). However, my code is failing for a really large test case for a matrix of dimension 50x50 after passing 74/80 test cases on Leetcode.
I tried to find out the source(s) that could be causing it to fail, but I am not really sure where the error is.
Any help would be appreciated. Thanks!
Please do let me know if further clarification about the code is needed
The calculation of antiDiagSum is wrong: it actually sums the values on the same diagonal as diagSum, just in reverse order. To traverse the opposite diagonal, you need to increment the Y coordinate and decrement the X coordinate (or vice versa), but your code decrements both of them.
It is probably easiest if you fix this by calculating both diagonal sums in the same loop:
for(int count = 0; count < k; count++){
diagSum += grid[startX][startY];
antiDiagSum += grid[endX][startY];
startX++, startY++, endX--;
}
Beginner here...
Doing a code to check language performance in Cpp, Java and Python.
The code must generate a random number N (1-60), fill a NxN matrix with random numbers between 0 and 9 and calculate its determinant.
I started with cpp, but sometimes it succeeds, sometimes it fails. My guess is that crashes are related to bigger than "long long int" numbers. Can you guys please check my code?
GNU GCC / CodeBlocks.
Thanks,
Guile.
#include <iostream>
#include <time.h>
using namespace std;
struct Mat{
int N = 2;
int mat[60][60];
long long int det;
};
void setSize(Mat *Size){
srand (time(NULL));
do {
Size->N = rand()%60;
}
while (Size->N < 1);
}
void setMatrix (Mat *mat){
srand (time(NULL));
for (int i = 0; i < mat->N; i++){
for (int j = 0; j < mat->N; j++){
mat->mat[i][j] = rand()%10;
}
}
}
void det(Mat *m1){
int i, j, k;
long long int Ratio;
long long int determinant;
for(i = 0; i < m1->N; i++){
for(j = 0; j < m1->N; j++){
if(j>i){
Ratio = m1->mat[j][i]/m1->mat[i][i];
for(k = 0; k < m1->N; k++){
m1->mat[j][k] -= Ratio * m1->mat[i][k];
}
}
}
}
determinant = 1;
for(i = 0; i < m1->N; i++)
determinant *= m1->mat[i][i];
m1->det = determinant;
}
int main (void){
Mat M1;
setSize(&M1);
setMatrix (&M1);
det(&M1);
cout<<"Matrix size: "<<M1.N<<endl;
cout<<"Matrix determinant: "<<M1.det<<"\n\n";
return 0;
}
Inside your function setMatrix:
for (int j = 0; j < mat->N; j++){
mat->mat[i][j] = rand()%10;
}
rand() % 10 can sometimes generate 0 as well, thus putting zeroes inside your matrix. This will cause a floating-point exception when you do:
Ratio = m1->mat[j][i]/m1->mat[i][i];
This line will again cause an issue when you do
m1->mat[j][k] -= Ratio * m1->mat[i][k];
which can again set a zero in your matrix at mat[j][k] later which can become the denominator again, causing the floating-point exception.
So far I have this code for an LU decomposition. It takes in an input array and it returns the lower and upper triangular matrix.
void LUFactorization ( int d, const double*S, double*L, double*U )
{
for(int k = 0; k < d; ++k){
if (
for(int j = k; j < d; ++j){
double sum = 0.;
for(int p = 0; p < k; ++p) {
sum+=L[k*d+p]*L[p*d+j];
cout << L[k*d+p] << endl;
}
sum = S[k*d+j] - sum;
L[k*d+j]=sum;
U[k*d+j]=sum;
}
for(int i = k + 1; i < d; ++i){
double sum=0.;
for(int p = 0; p < k; ++p) sum+=L[i*d+p]*L[p*d+k];
L[i*d+k]=(S[i*d+k]-sum)/L[k*d+k];
}
}
for(int k = 0; k < d; ++k){
for(int j = k; j < d; ++j){
if (k < j) L[k*d+j]=0;
else if (k == j) L[k*d+j]=1;
}
}
}
Is there some way I can adapt this to perform row exchanges? If not, is there some other algorithm I could be directed towards?
Thanks
The usual approach for LU decompositions with pivoting is to store a permutation array P which is initialized as the identity permutation (P={0,1,2,...,d - 1}) and then swapping entries in P instead of swapping rows in S
If you have this permutation array, every access to S must use P[i] instead of i for the row number.
Note that P itself is part of the output, since it represents the permutation matrix such that
P*A = L*U, so if you want to use it to solve systems of linear equations, you'll have to apply P on the right-hand side before applying backward and forward substitution
My program is tasked with sorting points on an x-y plane, given by the user, according to their distance from the origin using bucket sort. In the instance of having two points with the same distance, the point with the smallest x-coordinate would be selected as the first point. If both the distance and the x-coordinate are the same, the element with the smallest y-coordinate will come first. The output is the points themselves, not their distances. The most logical way I've found to do it so far is to create a custom data structure that houses both the x coordinate, y-coordinate, and its distance in one element. The problem I have at the moment is my current algorithm for standard vectors of doubles, and I have no idea how to convert the sort to fit my needs. Any ideas or suggestions would be helpful.
Here is the layout of the structure:
struct point {
double xc;
double yc;
double dist; };
The current bucket sort, which works fine with vectors of doubles.
void bucketSort(vector<double> &arr) {
int n = B.size();
vector<point> b[n];
for (int i=0; i<n; i++)
{
int bi = n*arr[i];
b[bi].push_back(arr[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++){
arr[index++] = b[i][j]; }
}
}
The entirety of the code, as of now.
using namespace std;
struct point {
double xc;
double yc;
double dist;
};
vector<double> A;
vector<double> B;
double findDistance(double x = 0, double y = 0) {
double x2 = pow(x, 2);
double y2 = pow(y, 2);
double z = x2 + y2;
double final = sqrt(z);
return final;
}
void bucketSort(vector<double> &arr)
{
int n = B.size();
vector<point> b[n];
for (int i=0; i<n; i++)
{
int bi = n*arr[i];
b[bi].push_back(arr[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++){
arr[index++] = b[i][j]; }
}
}
int main(){
double number; int t = 0;
while (cin >> number){
A.push_back(number); }
struct point C[A.size()];
while (t < A.size()){
C[t / 2].xc = A[t]; C[t / 2].yc = A[t + 1];
C[t / 2].dist = (findDistance(A[t], A[t + 1])); t += 2; }
cout << setprecision(6); cout << fixed; ;
bucketSort(C);
cout << showpos; cout << fixed;
int x = 0;
while (x < (A.size() / 2)){
cout << C[x].xc << " " << C[x].yc << endl;
x++;
}
}
A vector of doubles B is here because initially, I was trying to get it done with multiple vectors of doubles.
Here is a sample of the input:
0.2 0.38
0.6516 -0.1
-0.3 0.41
-0.38 0.2
Sample output:
-0.380000 +0.200000
+0.200000 +0.380000
-0.300000 +0.410000
+0.651600 -0.100000
I realize that point could have a lot more functions added to it to make it more usable in general, but I'm aiming for just enough to get the current job. Any suggestions or help would be greatly appreciated. Please and thank you.
I would suggest one of there 2 options -
make point a class, not an struct, and overload the < operator, thus making the sort work well.
2.use the sort by function instead of the normal sort:
Firstly, add a compare function:
bool comparePoint(point* a, point* b) {
return true if a < b;
}
the function above would compare the 2 points, according to any rules you like, depends on your code.
and instead of the sort use:
std::sort(b[i].begin(), b[i].end(),comparePoint);
that should work for you.
i want to potentiate a Matrix but i dont workings how it should work.
m ist the Matrix i want to potentiate
long double pro[100][100]; // product after each step
long double res[100][100]; // the Matrix with the exponent n
for (int n = 1; n < nVal; n++) // exponent
{
for (int i = 0; i < mVal; i++) // row
{
for (int j = 0; j < mVal; j++) // col
{
res[i][j] = 0;
for (int k = 0; k < mVal; k++) // inner
{
res[i][j] += pro[i][k] * m[k][j]; // multiply the product with the default matrix
}
}
}
}
// array Output - working
for (int i = 0; i<mVal; i++)
{
for (int j = 0; j<mVal; j++)
cout << res[i][j] << "\t";
cout << endl;
}
in the output i see some crazy numbers and i dont know why :(
Can anyone help me?
You should
initialise the pro matrix to the identity at the beginning of loop on n
copy the res matrix into the pro matrix the end of each loop on n.
In pseudo code
pro = Identity matrix
for (int n = 1; n < nVal; n++) {
res = pro * m // using two loops
pro = res
}
result is in pro.
Note that there are much faster way to compute powers: http://en.wikipedia.org/wiki/Exponentiation_by_squaring
As Willll said you shouldn't forget to initialize.
Another suggestion would be to erase the exponent loop and just use the pow() function from math library. It´ll make it more simple and easier to visualize.