LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

For Loop Indexing (Arrays)

Solved!
Go to solution

Hello and thanks for reading.

 

I have a problem that requires me to do a lot of manipulation with arrays, and I am trying to do this in a series of nested For Loops. I'll cut straight to my issue.

 

I initialize an array to 0 in a user-defined number of columns. I run a For Loop the user-defined number of times, generating a random value on every iteration. If I enable auto-indexing, I can use the Replace Array Subset outside the loop and it runs fine.

 

Here's my problem. If I disable auto-indexing, and wire from the [ i ] block to the index on the Replace Array Subset, now all of the sudden all I get is one random value, and it's always in the last slot in the array.

 

 

I've been pulling my hair out over this problem. I've looked at the forums, I've looked at the example problems, I have no idea WHY it's doing this, but I NEED to be able to use the loop counter to replace array elements. I am going to nest 3 For Loops, and I am not comfortable (familiar) enough with how the auto-indexing feature chooses which value to auto-index to be able to think through the problem.

 

I wrote the entire program in C in my head in about 10 minutes, but this auto-indexing thing is KILLING me and I have no idea how to import C into LabView without writing a dll, which I don't know how to do either. 

 

PLEASE let me know how I can get the For Loop to step through an array without using auto-indexing. Again, I have no idea why it's just posting a value in the last slot of the array. 

 

Many Thanks for all answers.

0 Kudos
Message 1 of 9
(6,963 Views)

Your for loop isn't stepping through any array. It iterates x number of times and passes a single value out. A single replace array happens. Your array would have to be inside the loop. This is no different than a program in c.

 

The autoindexing is simple and I don't understand the confusion. The first iteration gives you the first element, the second iteration gives you the second element, etc.

0 Kudos
Message 2 of 9
(6,955 Views)

Your For Loop may run N times, but ultimately you are only doing one replace array subset, and it is going to use the last number that comes out of the tunnel of the For Loop.

 

What you need to do is put your replace array subset inside the For Loop, and wire your array through the For Loop using a shift register to store the value of the array from one iteration to the next.

 

See attached.

0 Kudos
Message 3 of 9
(6,954 Views)

Replace array subset requires an existing array, it doesn't add or insert elements. Replacing outside the array limits only result in Null. This is what you're seeing. If you want to use your approach you'll need to initialize the array to a 2D array with "0 in a user-defined number of columns" and "I run a For Loop the user-defined number of times" as parameters.

 

Autoindex is always a single step walkthrough of an array.

Something like:

int[10] Array                            //wired array

for (i=0;i<length(Array);i++)       //Autoindex

  Replace_array[i] = Random(); //Something random similar to what you're doing now

 

At first a thought the autoindex left me "out of control", but how often do you really use it in a different manner than above? (apart from Step which has to be implemented by an i*X)

To me it feels like LV is abit more While than For-focused, and i tend to prefer For-loops, but that might be me ranting. 🙂

 

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 4 of 9
(6,940 Views)

Ravens,

 

  That works terrific, and I had looked at shift registers in the help files, but the help file doesn't really say much on what it does other than storing values between iterations. For your revised code, you have the initialized array pass through a shift register, you generate random numbers and put it into the array in the loop, then you pass it through another shift register before displaying it.

 

  I tried this code, identical to yours except no shift registers, and it has the same behavior as the code I had posted. From my background in C, the initial code that I posted didn't make much sense to me, but again, if I used auto-indexing, it works. I'm (still) not sure why the code I posted would work with auto-indexing but not with manual indexing. I can't tell why auto-indexing succeeds where manual indexing fails. 

 

  Is there anywhere I can read more about how to use shift registers? I'm curious why their addition makes the program work.

 

 

 

Yamaeda,

 

  I need to generate a 2D array of random values to represent the location of a swarm of robots. I need to find the distance from each point to every other point and display in another 2D array, and I need to find which points have an average distance under 20 to flag as potential leaders (from a communications point of view). Additionally, the fastest program in the class wins 10 points extra credit, so I'm trying to do as much in a step as possible, rather than running a loop [user defined] times for each step (generating points, distances, averaging, etc.). 

 

The code that I had imagined would be something like

 

int number_of_points, xsqr, ysqr, distance;

cin>>number_of_points;

 

int points_array[number_of_points][4];     //4 columns, 1 for x, 1 for y, 1 for a flag (average over 20), and 1 for the average distance

int distances_array[number_of_points][number_of_points]; //The distances array is a square array, from each point to every other point

 

for(i=0;i<number_of_points;i++)

{

points_array[ i ][0] = rand()%101;  //the 0 column is x

points_array[ i ][1] = rand()%101; //the 1 column is y

 

for(j=0;j<i;j++)

{

xsqr =( points_array[ i ][0] - points_array[ j ][0] )^2; //calculate the square of the x distance

ysqr =( points_array[ i ][1] - points_array[ i ][1] )^2; //and the y distance

 

distance = sqrt(xsqr + ysqr); //finish the Pythagorean theorem

distances_array[ i ][ j ] = distance;

distances_array[ j ][ i ] = distance;

 

points_array[ i ][3] = points_array[ i ][3] + (distance / number_of_points);

points_array[ j ][3] = points_array[ j ][3] + (distance / number_of_points);

//This adds the incremental average to the running average

 

if(points_array[ i ][3] >20) //If it's over the flag value, flag it

{points_array[ i ][2] = 1;}

else {points_array[ i ][2] = 0;}

  if(points_array[ i ][3] >20)

{points_array[ i ][2] = 1;}

else {points_array[ i ][2] = 0;}

}

j=0;

}

 

 

So the auto-indexing, while kinda nice, doesn't let me specify where the data is going to go. I want to put values in [ i ][ j ] AND in [ j ][ i ] so I don't have to run a lot of loops to get this done. I was taught recursion is superior to everything else, so the shorter the code the better. I'm not sure how to get this done without manually indexing the arrays, and I apparently can't do that without the shift registers. 

 

I'm still unsure as to how exactly the shift registers work (as noted above), but I'm going to play with them for a while later today to see if I can figure it all out. 

 

The incremental average there was, I thought, a clever work-around to avoid waiting until I had all the distances calculated to then find the average. And average of (n) number of points is (x1 + x2 + x3 + . . . ) / n .   Mathematically, this is the same as (x1/n) + (x2/n) + (x3/n) + . . . , so that's what I do in the program. By the end of the outer For Loop, the average distance is calculated. 

0 Kudos
Message 5 of 9
(6,913 Views)

@saundecp wrote:

Ravens,

 

  I'm (still) not sure why the code I posted would work with auto-indexing but not with manual indexing. I can't tell why auto-indexing succeeds where manual indexing fails. 

 


I would have to see your code with the array indexing enabled to figure that one out.  I think you must have some other differences in the code as well.

 

Shift registers are a basic LabVIEW concept that is covered  in the Basics 1 & 2 courses.  If you search LabVIEW help for "shift register" and look at the item called "Transferring values between loop iterations", you should see all you'll need to know about them.

0 Kudos
Message 6 of 9
(6,899 Views)

Dennis,

 

  I understand that my code only outputs one value. What I'm not understanding is, if I cut the [ i ] wire, and set the random number tunnel to auto-index, it works. 

 

Why would the auto-indexing output multiple values, but the manual indexing only output one value? Doesn't [ i ] change as the loop iterates? Wouldn't that then point to multiple positions in the array?

0 Kudos
Message 7 of 9
(6,897 Views)
Solution
Accepted by topic author saundecp

I know what it is.  I don't have LV 2010 here at work installed, so I have to rely on my memory and visualize the code.

 

You are using replace array subset.  With autoindexing turned on, you are creating a 1-D array of the random numbers that just happens to be the same length as your array because of the N terminal being wired up to the array length.  So you wind up replacing the entire 1-D array dimension in one shot with new data starting at element 0.  (For grins, wire up a smaller number to the N terminal and you'll see only a portion of your 1-D array is replaced.)

 

The way that I have shown, you are replacing data 1 element at a time, and the first iteration is for element 0, the next element 1, ....

Message 8 of 9
(6,887 Views)

That's exactly the answer I was looking for, and it makes sense.

 

On the plus side for me, I can avoid labview altogether (almost), and use the function node in programming to program C into labview lol. But, thanks for the answers, I really do appreciate it. It's so nice to come to a helpful forum!

 

Thanks again,

 

  Chuck Saunders

0 Kudos
Message 9 of 9
(6,870 Views)