Mapping a function across an array of structures
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I have created an array of structures for the x, y, and z coordinates of particles at time t. For example, suppose I have 3 particles and monitor the positions of the particles at five different times:
s(1).x=1.1:0.1:1.5;
s(1).y=2.1:0.1:2.5;
s(1).z=3.1:0.1:3.5;
s(2).x=4.1:0.1:4.5;
s(2).y=5.1:0.1:5.5;
s(2).z=6.1:0.1:6.5;
s(3).x=7.1:0.1:7.5;
s(3).y=8.1:0.1:8.5;
s(3).z=9.1:0.1:9.5;
For the purpose of this example, I have just made up the x, y, and z coordinates of the three particles at the five times. (My actual data is much more extensive; it contains information about 254 atoms at 2001 different times, but my structure organization is the same.)
Now suppose that I want to find the displacement of the ith particle at time t relative to its position at the first time. For this, I have written a function called delta:
function result = delta(i,t,structureName)
xvalinitial=structureName(i).x(1);
yvalinitial=structureName(i).y(1);
zvalinitial=structureName(i).z(1);
xval=structureName(i).x(t);
yval=structureName(i).y(t);
zval=structureName(i).z(t);
result=[xval-xvalinitial yval-yvalinitial zval-zvalinitial];
So if I call for example delta(1,2,s), I get the displacement of atom 1 at time 2, relative to atom 1's initial position:
>> delta(1,2,s)
ans =
0.1000 0.1000 0.1000
But, now, what if I wanted to vectorize my function delta? What if I wanted to be able to "map" delta across a vector. For example, ideally, I would like to be able to type:
delta([1 2 3],2,s)
and obtain a list of the displacements of atoms 1, 2, AND 3 at time 2 relative to the initial time, time 1.
Or, I might want to be able to type:
delta(1,[2 3],s)
and obtain a list of the displacement of atom 1 at the time 2 AND at the time 3, relative to the initial time, time 1.
(By "list," I guess I really mean "matrix" or "array", where each row contains x, y, and z coordinates for the delta of the atom(s) at the time(s).)
Can you please help me see how I might be able to write the delta function so that I am able to do this? Should I be using the built-in Matlab command structfun? I tried this, but I have not had success so far. Is there any other way that I can "map" my delta function across vectors?
Thanks in advance. Andrew DeYoung Carnegie Mellon University
0 commentaires
Réponse acceptée
Walter Roberson
le 9 Mai 2011
EDITED: corrected to "arrayfun"
selectx = @(i,t) cell2mat(arrayfun(@(S) {S.x([1 t])}, structureName(i)));
Likewise for y and z.
The resulting arrays will have one row per value of i, and the columns will be x(1) followed by one column per x(t). Take the first column and repmat() it to the width of the remaining columns and subtract that from the remaining columns in order to get your delta values.
Plus de réponses (2)
Andrew
le 9 Mai 2011
3 commentaires
Walter Roberson
le 9 Mai 2011
You can hide the "for" loop, but for "norm" you cannot really replace it.
arrayfun(@(K) norm(A(K,:)), 1:size(A,1))
If you want to do this kind of thing repeatedly then,
maprows = @(f,A) arrayfun(@(K) f(A(K,:)), 1:size(A,1))
then
maprows(@norm, A)
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!