Segmentation fault - trying to pass matlab code to c ++ - c++

I'm trying to pass a code that is in matlab for c ++ but it is giving segmentation fault (core dumped), can someone help me please?
Code in MATLAB
function strip = strips(strip,n,number_pixel)
se = strel('square', 3);
strip=imdilate(strip, se);
strip = imfill(strip);
[m1,n1] = size(strip);
vet=0;
for j=1:n1
for i=1:m1
if strip(i,j)==0
vet=vet+1;
end
end
aux(j)=vet;
vet=0;
end
limite=uint8(number_pixel/4);
for i=1:n1
if aux(i) < limite
strip(:, i)=1;
end
if aux(i) >= limite
strip(:, i)=0;
end
end
end
Code in C++
Mat strips(Mat strip, int n, int number_pixel){
int vet = 0;
int limite = (number_pixel/4);
int v[strip.cols];
dilate(strip, strip, getStructuringElement(MORPH_ELLIPSE, Size(3,3)));
strip = imfill(strip);
int n1 = strip.cols;
int m1 = strip.rows;
for (int j = 0; j < n1; j++){
for (int i = 0; i < m1; i++){
if(strip.at<uchar>(i, j) == 0){
vet += 1;
}
}
v[j] = vet;
vet = 0;
}
for (int i = 0; i < n1; i++){
int j;
if (v[i] < limite){
strip.at<uchar>(i, j) = 1;
}
if (v[i] >= limite){
strip.at<uchar>(i, j) = 0;
}
}
}
I already implemented the functions as imfill, I think my error is in the loop, but I can't find

It is very hard to tell what the problem is, when not having a fully working example. One obvious problem with your code is, that you use j uninitialized in your second loop:
for (int i = 0; i < n1; i++){
int j;
if (v[i] < limite){
strip.at<uchar>(i, j) = 1; // <- uninitialized j is used
}
//...
}
This is undefined behavior and basically everything could happen. j allocates memory but does not have a specific value. See this answer:
Local variables get their initial values from whatever random data is in the stack space they occupy at that moment.
That is j could be a very large integer and you try to access a value out of bounds. Or using j itself causes the error. As I said, the behavior is undefined.
EDIT I also think the second part of your code should be changed. strip(:,i)=1 sets the ith column of the 2D array to 1. Assuming that strip.at<uchar>(i, j) returns only a reference to a single value, your c++ code should be something like this:
for (int i = 0; i < n1; i++){
if (v[i] < limite){
// go through all rows and set the i-th column to 1.
for (int j = 0; j < m1; ++j)
strip.at<uchar>(j, i) = 1;
}
//...
}

Related

Partial Pivoting/Gaussian elimination- swapping columns instead of rows producing wrong output

I'm trying to implement a quick program to solve a system of linear equations. The program reads the input from a file and then writes the upper-triangular system and solutions to a file. It is working with no pivoting, but when I try to implement the pivoting it produces incorrect results.
As example input, here is the following system of equations:
w+2x-3y+4z=12
2w+2x-2y+3z=10
x+y=-1
w-x+y-2z=-4
I expect the results to be w=1, x=0, y=-1 and z=2. When I don't pivot, I get this answer (with some rounding error on x). When I add in the pivoting, I get the same numbers but in the wrong order: w=2,x=1,y=-1 and z=0.
What do I need to do to get these in the correct order? Am I missing a step somewhere? I need to do column swapping instead of rows because I need to adapt this to a parallel algorithm later that requires that. Here is the code that does the elimination and back substitution:
void gaussian_elimination(double** A, double* b, double* x, int n)
{
int maxIndex;
double temp;
int i;
for (int k = 0; k < n; k++)
{
i = k;
for (int j = k+1; j < n; j++)
{
if (abs(A[k][j]) > abs(A[k][i]))
{
i = j;
}
}
if (i != k)
{
for (int j = 0; j < n; j++)
{
temp = A[j][k];
A[j][k] = A[j][i];
A[j][i] = temp;
}
}
for (int j = k + 1; j < n; j++)
{
A[k][j] = A[k][j] / A[k][k];
}
b[k] = b[k] / A[k][k];
A[k][k] = 1;
for (i = k + 1; i < n; i++)
{
for (int j = k + 1; j < n; j++)
{
A[i][j] = A[i][j] - A[i][k] * A[k][j];
}
b[i] = b[i] - A[i][k] * b[k];
A[i][k] = 0;
}
}
}
void back_substitution(double**U, double*x, double*y, int n)
{
for (int k = n - 1; k >= 0; k--)
{
x[k] = y[k];
for (int i = k - 1; i >= 0; i--)
{
y[i] = y[i] - x[k]*U[i][k];
}
}
}
I believe what you implemented is actually complete pivoting.
With complete pivoting, you must keep track of the permutation of columns, and apply the same permutation to your answer.
You can do this with an array {0, 1, ..., n}, where you swap the i'th and k'th values in the second loop. Then, rearange the solution using this array.
If what you were trying to do is partial pivoting, you need to look for the maximum in the respective row, and swap the rows and the values of 'b' accordingly.

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

C++ Vague behavior of uninitialized variable [duplicate]

This question already has answers here:
Default variable value
(10 answers)
Closed 7 years ago.
The below code behaves as if I have initialized variable res to 0, if I uncomment the lines above the first time I used it.
int t, mi,cur,n,res;
scanf("%d",&t);
while(t-- && scanf("%d",&n) == 1)
{
for (int i = 1; i <= n; ++i)
{
scanf("%d",&h[i]);
}
for (int i = 1; i <= n; ++i)
{
scanf("%d",&k[i]);
}
for (int i = 0; i < 1001; ++i)
dp[0][i] = INF;
for (int i = 0; i < 501; ++i)
dp[i][0] = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= 2*n; ++j)
{
dp[i][j] = dp[i-1][j];
if(j >= k[i-1])
dp[i][j] = min(dp[i-1][j],1 + dp[i][j-k[i-1]]);
}
}
// The lines below.
//for (int i = 0; i <= n; ++i)
//{
// for (int j = 0; j <= 2*n; ++j)
// {
// printf("%d ", dp[i][j]);
// }
// printf("\n");
//}
for (int i = 1; i <= n; ++i)
{
res += dp[n][2*h[i]];
}
printf("%d\n", res);
When I print the value of res with the lines commented, it gives me garbage value, but when I uncomment it, it gives me the expected value. I don't know the advanced concepts of the language. Why this happens?
dp[0][*] and dp[*][0] are not initialized as you fill your array starting at index 1.
Then, if h[i] is 0, you will definitely copy an unitialized value to res.
The advanced concepts of the language in this case is just that uninitialized variables leads to undefined behaviour and should not be used. See Default variable value (as commented by Kelvin Lai).
So you may accept that and don't try to figure out why printing the values fix the problem....because there is no point trying to determine how undefined behaviours are working...;-)
Note: The fact that comented lines in your post fixe the problem may be compiler/platform/configuration specific. It's just a kind of corner case that fixes the issue of your uninitialized variables being used when they should not...

Trying to multiply two dynamically created matrices(2d vector's) together in c++

So what I am trying to do is multiply one 2d vector by another 2d vector.
I come from Java,Python and C# so I am pretty much learning C++ as I go along.
I have the code down to generate the vector and display the vector but I can't seem to finish the multiplication part.
v1 is another matrix that is already generated.
vector<vector<int> > v2 = getVector();
int n1 = v1[0].size();
int n2 = v2.size();
vector<int> a1(n2, 0);
vector<vector<int> > ans(n1, a1);
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
for (int k = 0; k < 10; k++) {
// same as z[i][j] = z[i][j] + x[i][k] * y[k][j];
ans[i][j] += v1[i][k] * v2[k][j];
}
}
}
displayVector(ans);
My guess for where I am going wrong is in the inner-most loop. I can't figure out what to actually put in place of that 10 I have there now.
When you multiply matrices, the number of columns of the matrix on the left side must equal the number of rows of the matrix on the right side. You need to check that that is true, and use that common number for your size of the k variable:
int nCommon = v1.size();
assert(v2[0].size() == nCommon);
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
for (int k = 0; k < nCommon ; k++) {
ans[i][j] += v1[i][k] * v2[k][j];
}
}
}
For you inner loop, you should do something like this
ans[i][j] = 0;
for (int k = 0; k < n2; k++) {
ans[i][j] += v1[i][k] * v2[k][j];
}
I don't know where the 10 comes from.

c++ equivalent to matlab max(find(array < x) and min(find(array > x)

what would be the c++ equivalent to this matlab code? I started it off but i'm not sure what value B would be, i think A is correct.
MATLAB
array = (-1:.001:1)';
A = max(find(array < 1.0e-2));
B = min(find(array > 1 - 1.0e-2));
C++ attempt
for(i = 0; i < array.size; i++){
if(array[i] < 1.0e-2){
k++
A = k;
}
if(array[i] > (1- 1.0e-2)){
//not sure what to do here
B = ?;
}
}
for(i = 0; i < array.size; i++){ // Would be faster if you reversed loop direction
if(array[i] < 1.0e-2)
A = i;
}
for(i = 0; i < array.size; i++) {
if(array[i] > 1-1.0e-2) {
B = i;
break;
}
}
For the second bit, I would do this instead inside the same loop:
if(array[array.size-i-1] > (1 - 1.0e-2)) B = array.size - i;
and initialize B to array.size before the loop.
Essentially, you are finding the element with the lowest index in the array which is also larger than 1 - 1.0e-2. If you start at the element with the highest index and then traverse the entire array and update each time you satisfy the criteria, you will end up with what you need. A similar logic applies for the first part, but you will need to set A = i+1 instead of incrementing k because there is no guarantee the array is sorted.
Basically the command A = max(find(array < 1.0e-2)); Is looking for the largest index of the array that is greater than 1.02e-2.
To see how this happens just break down the statement into parts:
array < 1.0e-2) returns a vector of logical indices.
find( ... ) converts the logical indices to numeric indices
max(...) returns the largest value from the list of numeric indices.
A C++ equivalent would look something like:
int A = -1;
int maxVal = 1.0e-2;
for (int i = array.length-1; i>=0; i--)
if (array[i] < maxVal){
A = i;
break;
}
To get B just setup another loop:
int B = -1;
int minVal = 1 - 1.0e-2;
for (int i=0; i<array.length; i++)
if (array[i] > minVal){
B = i;
break;
}