I am implementing the guo hall algorithm for a micro controller. The problem is due to it's architecture I cannot use opencv. I have the algorithm working fine except for one problem. in the following code a struct is passed through the thinning iterator the struct contains both the 2d array and a boolean determining whether or not change was made to the array.
int* thinning(int* it, int x, int y)
{
for(int i= 0; i < x*y; ++i)
it[i] /= 255;
struct IterRet base;
base.i = it;
base.b = false;
do
{
base = thinningIteration(base, x, y, 0);
base = thinningIteration(base, x, y, 1);
}
while (base.b);
for(int i= 0; i < x*y; ++i)
base.i[i] *= 255;
return base.i;
}
when I change the while condition to while(0) A single iteration passes and the matrix is properly returned.
When I leave the while loop as is, it goes on indefinitely.
I have narrowed the problem down to the fact that base is reset after each run of the do-while loop.
What would cause this? I can give more code if this is too narrow of a view for it.
I ran your code as it is, it did not go on indefinitely, but ran through once, and stopped. However, there are two places where I made a suggested change. Really just a readability/style thing, not something that will change the behavior of your code in this case.
See commented and replacement lines below.
In thinningIteration()
struct IterRet thinningIteration(struct IterRet it, int x, int y, int iter)
{
//int* marker = malloc(x*y* sizeof *marker);
int* marker = malloc(x*y* sizeof(int));
In main()
//int* src = malloc( sizeof *src * x * y);
int* src = malloc( sizeof (int) * x * y);
Unfortunately, these edits did not address the main issue you asked about, but again, running the code did not exhibit the behavior you described.
If you can add more about the nature of your observed issues, please leave a comment, and if I can, will attempt to help.
Related
I have to answer a question about a relatively simple C-code snippet. In the function below, what would be the most costly in terms of performance or time complexity? I really have no idea how to answer that because I feel it depends on the if-statement. Also I don't know if a comparison is costly or not, same goes for a return, a struct access and multiplication.
Btw, the info_h is a struct.
RGBPixel* bm_get_pixel_at(
unsigned int x,
unsigned int y,
RGBPixel *pixel_array )
{
int index;
int width_with_padding = info_h.width;
if( x >= info_h.width || y >= info_h.height ){ return &blackPixel; }
index = (info_h.height-1 - y) * width_with_padding + x;
return pixel_array + index;
}
EDIT:
Okay so the question might have been a bit oddly phrased. I should add that this is just one function out of many in a bit more complex c program which we have now ran a oprofile script thirty times on. The script then returns the results of average times each procedure was sampled by oprofile. In that results table, this function came in at third most sampled. The follow up question is therefore, which part of this function causes the program to spend third most of its time inside it? Sorry if it was a bit unclear in the beginning
Since you've omitted the rest of your program, it all turns into guesswork. That this function shows up a lot in your profiling result is likely due to it being called inside an inner loop. What this function does (it's pretty obvious) is, that it returns the memory location of a pixel or, if the requested index lies outside of the bounds of the pixel array, returns the memory location of a dummy pixel.
If you run that function inside a loop, then the bounds check is executed for each and every iteration, which of course is quite redundant. This is a really low-hanging fruit regarding optimization: Put the bounds checks before the loop, and make sure, that the loop itself doesn't venture outside the bounds:
static inline
RGBPixel* bm_get_pixel_at_UNSAFE(
unsigned int x,
unsigned int y,
RGBPixel *pixel_array )
{
size_t const width_with_padding = info_h.width;
size_t const index = ((size_t)info_h.height-1 - y) * width_with_padding + x;
return &pixel_array[index];
}
RGBPixel* bm_get_pixel_at(
unsigned int x,
unsigned int y,
RGBPixel *pixel_array )
{
return ( x < info_h.width && y < info_h.height ) ?
bm_get_pixel_at_UNSAFE(x,y, pixel_array)
: &blackPixel;
}
void foo(RGBPixel *pixel_array)
{
/* iteration stays inside array bounds */
for( unsigned int y = 0; y < info_h.height; ++y )
for( unsigned int x = 0; x < info_h.width; ++x ){
RGBPixel *px = bm_get_pixel_at_UNSAFE(x, y, pixel_array);
/* ... */
}
}
part of the program I'm writing involves making a function to test assertions. This one is testing my Shift3DPoint function, which takes the first array and modifies it by adding the contents of the second array (so for example, test14 and test15 (as seen below) would result with the new test14 {6,8,0}. However, I'm confused about how I can word this in my function because it's supposed to return an array and I've only worked with doubles before for assert. Any help would be appreciated!
void UnitTest3D(void); //function for assertions
void Shift3DPoint (double pt[], double offset[]);
void UnitTest3D(void){
double test13[3] = {0,0,0};
double test14[3] = {6,0,0};
double test15[3] = {0,8,0};
assert(UnitTest3D(test13, test14) ???
return;
}
void Shift3DPoint(double pt[], double offset[]) {
int i = 0;
for (i = 0; i < 3; ++i) {
pt[i] = pt[i] + offset[i]; //changes array contents by adding corresponding ptB
}
return;
}
assert is just a helper function you may or may not use. If you want to use assert explicitly (maybe because it aborts your program if it fails) you can write the test itself and then test it with assert. In your case, it would be that the test14 would have an expected value. How I would treat the thing, at first sight could be:
void UnitTest3D(void){
double test14[3] = {6,0,0};
double test15[3] = {0,8,0};
double expected_result[3] = {6,8,0};
// Test the result after calling the function
Shift3DPoint(test14, test15);
for (int i = 0; i < 3; ++i)
assert(test14[i] == expected_result[i]);
return;
}
(note that you have the call with different arrays, but I think you get the point). You can write helper macros or more generic functions, but you get the idea.
Also, take into account that double values are rarely checked with ==, as precission issues arise, so you should give some kind of epsilon, for the precission you want your calculations to be held:
assert ( fabs(test14[i] - expected_result[i]) < epsilon);
I'm still fairly new to c and i can't seem to understand this small bit of code.
void daxpy(int N, double alpha, double *x, double *y)
y=alpha*x+y
for (i=0, i<N, i++)
y[1]=alpha*x[1]+y[1];
i don't seem to know what daxpy function is doing or even its purpose. I know its probably something not very difficult. any help will be much appreciated. this was on my notes. I was just curious about what it was. I know the obvious things like daxpy is a function call. but just need a small explanation on it
I would think the actual code is like this:
void daxpy(int N, double alpha, double *x, double *y)
{
for (int i = 0, i < N, i++)
y[i]= alpha * x[i] + y[i];
}
This is because when looking at your code y = alpha * x + y does not seem to make sense. As x and y seems to be array, it should not work that way.
Furthermore, the following code is a loop, which I would think it explains the statement of y = alpha * x + y itself. And the number in the indices should be i instead of 1, because it is a loop from 0 to N. It does not make sense to put 1 there.
So that function call is basically just to add every element of array y with it's corresponding value in x multiplied by a constant alpha.
I'm trying to optimize some of my code in C, which is a lot bigger than the snippet below. Coming from Python, I wonder whether you can simply multiply an entire array by a number like I do below.
Evidently, it does not work the way I do it below. Is there any other way that achieves the same thing, or do I have to step through the entire array as in the for loop?
void main()
{
int i;
float data[] = {1.,2.,3.,4.,5.};
//this fails
data *= 5.0;
//this works
for(i = 0; i < 5; i++) data[i] *= 5.0;
}
There is no short-cut you have to step through each element of the array.
Note however that in your example, you may achieve a speedup by using int rather than float for both your data and multiplier.
If you want to, you can do what you want through BLAS, Basic Linear Algebra Subprograms, which is optimised. This is not in the C standard, it is a package which you have to install yourself.
Sample code to achieve what you want:
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {
int limit =10;
float *a = calloc( limit, sizeof(float));
for ( int i = 0; i < limit ; i++){
a[i] = i;
}
cblas_sscal( limit , 0.5f, a, 1);
for ( int i = 0; i < limit ; i++){
printf("%3f, " , a[i]);
}
printf("\n");
}
The names of the functions is not obvious, but reading the guidelines you might start to guess what BLAS functions does. sscal() can be split into s for single precision and scal for scale, which means that this function works on floats. The same function for double precision is called dscal().
If you need to scale a vector with a constant and adding it to another, BLAS got a function for that too:
saxpy()
s a x p y
float a*x + y
y[i] += a*x
As you might guess there is a daxpy() too which works on doubles.
I'm afraid that, in C, you will have to use for(i = 0; i < 5; i++) data[i] *= 5.0;.
Python allows for so many more "shortcuts"; however, in C, you have to access each element and then manipulate those values.
Using the for-loop would be the shortest way to accomplish what you're trying to do to the array.
EDIT: If you have a large amount of data, there are more efficient (in terms of running time) ways to multiply 5 to each value. Check out loop tiling, for example.
data *= 5.0;
Here data is address of array which is constant.
if you want to multiply the first value in that array then use * operator as below.
*data *= 5.0;
My problem is that the correct value that is suppose to be stored in the data[i].Px isn't stored and the same with the data[i].Py.
My formula in the do-while is faulty or must be.
The formula should calculate the 'position' of a projectile.
Vx and Vy is the initial velocities/values and Px and Py is the positions (in the x and y directions)
typedef struct
{
float t, Vx, Vy, Px, Py;
}datapoint;
steps = 100
data[0].Vx = (20*(cos(30))); //in my program 30 is in radians
data[0].Vy = (20*(sin(30));
data[0].Px = 0;
data[0].Py = 0;
do
{
i=1;
printf("Time: %.2f\t",i*q5);
//X
data[i].Vx = data[i-1].Vx;
data[i].Px = ((data[i-1].Px) + ((data[i].Vx) * i));
printf("X = %.2f\t",data[i].Px);
//Y
data[i].Vy= data[i-1].Vy - (9.81)*i;
data[i].Py= data[i-1].Py + (data[i].Vy * i);
printf("Y = %.2f\t", data[i].Py);
printf("\n");
i++;
}while(**(data[i].Py >0)** && (i<=steps));
In the while condition of the do while loop, do you want to have
while((data[i].Py > 0) && (i <= steps));
Oh just saw a flaw. Why are you initializing i=1 inside the loop! Its value will never go beyond 2.
(I just skimmed through your question, so if this doesn't work I will check it thoroughly).
Judging from the notation used (since the declaration is not shown), data is an array of datapoint. Then data->Px is equivalent to data[0].Px.
You don't show how data[0] is initialized.
i never gets beyond 2. Unless steps is 2, the loop won't terminate because of the i <= steps condition. Since the value in data[0].Py (aka data->Py) is not modified in the loop, you have an infinite loop unless data[0].Py is negative or zero on entry to the loop.
You should look askance at a do { ... } while (...); loop. They aren't automatically wrong; but they are used far less often than while or for loops.
Generally, you will get better answers on StackOverflow if you produce a minimal compilable and runnable program (or a minimal non-compilable program that illustrates the syntax error if you are having problems making the program compilable). And 'minimal' means that nothing can be removed without altering the behaviour.