How to declare variables in for loop? (IDL)

2019-07-18 23:50发布

问题:

For example,

My files are naming after 00.dat, 01.dat, 02.dat..., each file contains multiple columns and I use READCOL to read them into variables.

for i = 0, n-1 do begin
    readcol, string(i, F='(I02)')+'.dat', F='D,D', a0, b0
    readcol, string(i, F='(I02)')+'.dat', F='D,D', a1, b1
    .
    .
    c1 = a1 / a0
    c2 = a2 / a0
    .
    .
    d1 = b1 / b0
    d2 = b2 / b0
    .
    .
endfor

This works fine, but I cannot type all the varialbes one by one if there will be, say, one hundred variables.

Therefore, I want to use for loop to generate: a(i), b(i), c(i), d(i). In that sense, the code will look like:

for i = 0, n-1 do begin
    readcol, string(i, F='(I02)')+'.dat',F='D,D', a(i), b(i)
endfor

for i = 0, n-1 do begin
    c(i) = a(i) / a(0)
    d(i) = b(i) / b(0)
endfor

But this doesn't work, is there any method to declare variables in a for loop and while doing math?

(I am not a native English speaker. Please let me know If there is anything unclear in my question. Thank you!)

回答1:

Nice to see another IDL programmer on StackOverflow!

I think part of the problem is that READCOL is expecting simple variable names for its outputs, and in your second example you're giving it array expressions like a(i) and b(i) instead of a and b.

If I understand your question correctly, you want to replace the 1-dimensional arrays a0, a1, b0, b1, etc. from your first example, with 2-dimensional arrays a, b, etc. where each array has dimensions (nfiles, samples_per_file). So if you know in advance how many lines will be read from each file, you could do something like this:

a=dblarr(n,samples_per_file)
b=dblarr(n,samples_per_file)
; similarly for c, d, etc.

for i = 0, n-1 do begin
    readcol, string(i, F='(I02)')+'.dat',F='D,D', x, y
    a[i,*] = x
    b[i,*] = y
    c[i,*] = x/x[0]
    d[i,*] = y/y[0]
endfor

This version passes READCOL the simple variable names it's expecting, then copies them into subarrays of the 2-D variables.

If you don't know in advance how many samples are in each file, you could allocate the 2-d arrays during the first loop iteration:

for i = 0, n-1 do begin
    readcol, string(i, F='(I02)')+'.dat',F='D,D', x, y
    if (i EQ 0) then begin
       samples_per_file = n_elements(x)
       a = dblarr(n, samples_per_file)
       b = dblarr(n, samples_per_file)
       c = dblarr(n, samples_per_file)
       d = dblarr(n, samples_per_file)
    endif
    a[i,*] = x
    b[i,*] = y
    c[i,*] = x/x[0]
    d[i,*] = y/y[0]
endfor

Of course, this all assumes that each file contains the same number of samples. If not, you'd probably need to change a, b, c, and d to 1-dimensional arrays of pointers, then use PTR_NEW to allocate memory for each file's data as you read it.

(Note that I've used the square bracket [] notation for array indexing, which I find a bit easier to read than a(i), b(i) etc. which can be confused with function calls.)