On Monday 28 July 2003 10:48 am, Norbert Weiher wrote:
I know there are some good PERL hackers around. So do you have an idea how to do this? Recursion shurely helps - I experimented a lot with it but it still does not do what I need it to do. Just for your convenience: I stored the parameters in an array of hashes, so that I can have something like
$shell[0]{E0} = $something $shell[0]{dr} = $somethingelse...
So the loop for one shell is just looping through the hashkeys of element 0 of this array...
Hi Norbert, I am not certain that I understand the problem as you explained it, but it seems that what you need to do is to harvest the entire list of parameters that need to be varied from the array of hashes. Your data structure (the AoH) is an excellent one for storing the data, but isn't the right one for exploring the surface. Probably there is no single data structure that will do everything you want, so you end up needing to spend time shuffling data between different structures. Initially define @shell as a zero-length array like so: my @shell = (); Perl will autovivify new array elements as needed. Thus, for a one shell fit, you will do $shell[0]{e0} = $parameter_1; $shell[0]{delr} = $parameter_2; ## and so on... When and if you need a second shell, the next array element will spring into existance whenever you do something like this: $shell[1]{e0} = $parameter_N; and will *not* spring into existence *unless* you do something like that. To get a list of all the parameters, try this: my @parameter_list = (); foreach my $i (0 .. $#shells) { foreach my $k (keys %{$shell[$i]}) { push @parameter_list, $shell[$i]{$k}; }; }; This little idiom will fill @parameter_list with all the parameters with no prior knowledge of how many shells you actually defined. Indeed, you can add such things as the third cumulant and Ei to the fit without fretting that @parameter_list will miss them. You can also do clever things like checking $shell[$i]{$k} against the current contents of @parameter_list. This will allow you to use the same parameter for, say, e0 for each path without varying it against itself when you go to measure the surface. (Use recipe 4.6 in "The Perl Cookbook" by Christiansen and Torkington -- highly recommended if you do not already have a copy. I usually use the solution labeled "faster but different".) HTH, B P.S. The object oriented programming purist would insist that you should create an object based on your array of hashes and define a method to return the list of parameters. That's not wrong and it's highly reusable, but it may be overkill for your current project. In any case, all the method would do is shuffle data between data structures using nested foreach loops. -- Bruce Ravel ----------------------------------- ravel@phys.washington.edu Code 6134, Building 3, Room 222 Naval Research Laboratory phone: (1) 202 767 5947 Washington DC 20375, USA fax: (1) 202 767 1697 NRL Synchrotron Radiation Consortium (NRL-SRC) Beamlines X11a, X11b, X23b, X24c, U4b National Synchrotron Light Source Brookhaven National Laboratory, Upton, NY 11973 My homepage: http://feff.phys.washington.edu/~ravel EXAFS software: http://feff.phys.washington.edu/~ravel/software/exafs/