|
Hello everyone,
I am unable to figure how to code the following in C++. It is quite simple when the dimensions of the input array is preset. However, I am at a loss on how to do this when that is not the case.
So, just to explain I have an array which represent values in a multidimensional histogram. For the sake of argument, let us assume that the histogram is 3 dimensional and the x-dimension is of size 10, y dimension is of size 20 and z-dimension is of size 30.
Now, what I want to do is traverse through the histogram along each of the axes. So I want to go through the whole histogram along the rows, columns and the normal axes. If I hard-code the dimensions of the histogram it is quite easy to do so:
void traverse_histogram(float *histogram)
{
int index;
for (int z = 0; z < 30; ++z)
{
for (int y = 0; y < 20; ++y)
{
for (int x = 0; x < 10; ++x)
{
index = z * 20 * 10 + y * 10 + x;
}
}
}
for (int z = 0; z < 30; ++z)
{
for (int x = 0; x < 10; ++x)
{
for (int y = 0; y < 20; ++y)
{
index = z * 20 * 10 + y * 10 + x;
}
}
}
for (int y = 0; y < 20; ++y)
{
for (int x = 0; x < 10; ++x)
{
for (int z = 0; z < 30; ++z)
{
index = z * 20 * 10 + y * 10 + x;
}
}
}
}
Now, what I have is a situation where the dimensions are not hard-coded (they also can be more than 3) and what I need to do is generalize this somehow, so that it works when the number of dimensions and the dimension size are also dynamic. However, I am really struggling to figure out how this might work.
So, the new function signature is as follows:
void traverse_histogram(float *histogram, int num_dims, int *dimensions)
{}
I would be really grateful if someone can help me figure out a good way to do this. I am really stumped.
Thanks,
Keith
|
|
|
|
|
Firstly recognise that the generic index is calculated as follows:
index = X0 + X1*D0 + X2*D1*D0 + ... + Xn*Dn-1*Dn-2*...*D0
Where Xi is the index in axis i and Di is the size of dimension i
To make this word we need an array of the same size as the dimension array to hold each of the indices along the axes. Given this, the following code will calulate the index:
int calculate_product(int dim, int *dimensions)
{
int product = 1;
for(int i = 0; i < dim; ++i)
product *= dimensions[i];
return product;
}
int calculate_index(int num_dims, int *dimensions, int *indices)
{
int index = 0;
for(int i = 0; i < num_dims; ++i)
index += indices[i]*calculate_product(i, dimensions);
return index;
}
If we want to traverse along axis i, the outer loop should iterate over axis i - 1, the next loop iterates over axis i - 2, ..., then iterate over axis 0, then iterate over axis num_dims - 1, ..., then axis i + 1, and finally over axis i. First we need a function to get the previous axis number:
int previous(int current, int num_dims)
{
if(current > 0)
return current - 1;
return num_dims - 1;
}
Now to traverse the array, starting from a given axis, it is easiest to use recursion.
void traverse(int axis, int current, float *histogram, int num_dims, int *dimensions, int *indices)
{
for(indices[current] = 0; indices[current] < dimensions[current]; ++indices[current])
{
if(axis == current)
{
int index = calculate_index(num_dims, dimensions, indices);
}
else
{
traverse(axis, previous(current, num_dims), histogram, num_dims, dimensions, indices);
}
}
}
void traverse_axis(int axis, float *histogram, int num_dims, int *dimensions)
{
int *indices = new int[num_dims];
for(int dim = 0; dim < num_dims; ++dim)
indices[0] = 0;
traverse(axis, previous(axis, num_dims), histogram, num_dims, dimensions, indices);
delete [] indices;
}
void traverse_histogram(float *histogram, int num_dims, int *dimensions)
{
traverse_axis(num_dims - 1, histogram, num_dims, dimensions);
traverse_axis(num_dims - 1, histogram, num_dims, dimensions);
traverse_axis(1, histogram, num_dims, dimensions);
traverse_axis(0, histogram, num_dims, dimensions);
}
Graham
Librarians rule, Ook!
|
|
|
|
|
Thanks for such a detailed reply! I will give this a go.
Keith
|
|
|
|
|
Hello,
Just a quick clarification: In your traverse_axis code, you have:
for(int dim = 0; dim < num_dims; ++dim)
indices[0] = 0;
I am guessing you meant indices[dim] = 0 or something else as this seems to be not right.
Many thanks,
Keith
|
|
|
|
|
Keith Vitali wrote: I am guessing you meant indices[dim] = 0
Oops - yes, you are correct
Graham
Librarians rule, Ook!
|
|
|
|
|
Thanks for that.
The code seems to work fine. I would have never figured this out on my own!
/K
|
|
|
|
|
If you're using C++ leave all your C baggage behind. While the solution outlined would be great for C why not wrap all the messing about with dimensions to a class? You can bung the dimensions in the class along with your data and not have to fiddle about with pointers so much and all the errors that that produces (for example not having enough data for the number of dimensions).
Cheers,
Ash
|
|
|
|
|
hello guys...how can I learn that whether a particular feature is good to implememnt or not? Lets suppose that I use templates in my C++ prog, now how can I know that this is good to implement it or not??
|
|
|
|
|
Only experience will help you. Good news that it need not be your experience, it could just as well be someone else's. Read a book on design patterns or design practices. Design Patterns: Elements of Reusable Object-Oriented Software[^] is one place to start. I would say googling would be a good option, but admittedly might be hard if you don't know what key words to search for. If you're in doubt, you could drop a specific or general design question on a forum close to you.
The best shortcut to experience is to get a mentor.
|
|
|
|
|
thanks....the book looks to be good one.
|
|
|
|
|
overloaded Name wrote: Lets suppose that I use templates in my C++ prog, now how can I know that this is good to implement it or not??
Do they benefit, or add to the functionality of, the project? Can you complete the project without them?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
There was hardly any project/assignment in which I used templates. I just asked it.
|
|
|
|
|
overloaded Name wrote: how can I know that this is good to implement it or not??
Experience and failure more than success itself will tell you that using a language feature will be beneficial to your project.
why not success ? because at some point you will use one feature on the based of false previous success in a situation where it will fail miserably and you will need to re-evaluate your notions about that feature.
Anyway, good luck with it, it's always fun (when possible) to learn new features.
Watched code never compiles.
|
|
|
|
|
Read, lots. Try out different things. Make sure you've got a shelf load of C++ morality guides to back you up ("Effective C++" and "Exceptional C++" are good places to start).
As you try things out you'll find out if it's a good idea as your projects get bigger. For example extensive use of templates can slow the compiler down to a crawl. It's not a problem with 10 source files but with a couple of hundred it can be time for a tea break when you change one. Remember that language features in isolation rarely make that much of a difference to coding style (except perhaps for virtual functions, templates and exceptions) but when used together they can help and hinder a lot more.
Cheers,
Ash
|
|
|
|
|
Hi all,
i m using this to get edit box data line by line but here CEdit::GetLine return blank value when LineLength is 1.
CString strText, strLine;
for (i=0; i < nLineCount; i++)
{
int len = m_myEdit.LineLength(m_myEdit.LineIndex(i));
m_myEdit.GetLine(i, strText.GetBuffer(len), len);
strText.ReleaseBuffer(len);
strLine.Format(_T("line %d: '%s'\n"), i, strText);
}
please help me for this.
thank in advance.
|
|
|
|
|
You should make use of the return value from the function (see here[^]), and inspect the contents of your buffer if it only returns one byte.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
Le@rner wrote: int len = m_myEdit.LineLength(m_myEdit.LineIndex(i));
Try:
int len = m_myEdit.LineLength(i);
...
strText.ReleaseBuffer();
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
hi all,
i want to create thread pool in my application.
please help me how can i do this.
please me any suggestion and example for it.
thanks in advance.
|
|
|
|
|
See Thread Pool API[^]. I used QueueUserWorkItem()[^] to add work items. That's because I was working on Windows XP. But I assume that there are better things to do (see the "current api" column on the first link page) if you are using Vista or above.
There are some really weird people on this planet - MIM.
|
|
|
|
|
|
Hi all,
I am making a sdi application in which i am making various tasks. All tasks are performing a single operation. Now my problem is i want that all the task should start at the same time. One more thing i have to Repetitively
perform that operation from my task.
Now i am not getting what method to use. Either i should use thread pooling or some other technique.
|
|
|
|
|
learningvisualc wrote: Now my problem is i want that all the task should start at the same time.
How can such a thing be done? Even if we have a quad core processor, and each execute one thread at a time independent of each other, then your most optimistic chances are to start 4 such tasks at the same time.
May be you should explain your requirements a bit more clearly.
There are some really weird people on this planet - MIM.
|
|
|
|
|
Does anyone know how (from C/C++) check if an EXE file is code signed / digitally signed? And how to get the company name that has signed the file?
I need to create a function (in C/C++) that starts an EXE file with a known filename, but for security reasons I must first check that this is the original file (check that nobody has replaced the file with another one with same filename).
I know how to get version information from an EXE file, but reading code signing info will make the function much safer.
|
|
|
|
|
Can't you instead generate an MD5 hash code from the exe and check that against a valid value to see if the exe was replaced or not?
Anyways, a little googling brought me to this[^], i guess you can go on from there...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
modified on Friday, October 15, 2010 4:20 PM
|
|
|
|
|
Thank you for your link. I think this will solve my problem. I will take a closer look.
|
|
|
|
|