Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to write a script that matches a particular element to a coordinate. Let's say there are 24 coordinates; and that fractionally a:b:c:d:e is 18%:18%:18%:18%:27%. Instead of matching 4 of a, b, c, and d to individual coordinates and e to the final 8 (to a sum of 24), I want to generate a list of 24 points from my initial list of a,b,c,d,e and those percentages and then randomly pair them to available coordinates.

The current code I'm using is below, is there an easier way to do this?

Inputs:

elements = Transpose[{{aa, bb, cc, dd, ee}}]
xelement = {0.09, 0.09, 0.09, 0.09, 0.18};
spin = Transpose[{{"Spin=4", "Spin=3", "Spin=3", "Spin=2", 
 "Spin=2"}}];

PosFCC = {
{0.000000, 0.250000, 0.500000 }, 
{0.166667, 0.750000, 0.000000 }, 
{0.333333, 0.750000, 0.500000 }, 
{0.666667, 0.750000, 0.500000 }, 
{0.833333, 0.500000, 0.500000 }, 
{0.833333, 0.250000, 0.000000 }, 
{0.333333, 0.500000, 0.000000 }, 
{0.500000, 0.750000, 0.000000 }, 
{0.833333, 0.750000, 0.000000 }, 
{0.000000, 0.000000, 0.000000 }, 
{0.000000, 0.500000, 0.000000 }, 
{0.333333, 0.000000, 0.000000 }, 
{0.000000, 0.750000, 0.500000 }, 
{0.500000, 0.000000, 0.500000 }, 
{0.166667, 0.000000, 0.500000 }, 
{0.166667, 0.250000, 0.000000 }, 
{0.666667, 0.500000, 0.000000 }, 
{0.500000, 0.500000, 0.500000 }, 
{0.666667, 0.250000, 0.500000 }, 
{0.166667, 0.500000, 0.500000 }, 
{0.333333, 0.250000, 0.500000 }, 
{0.666667, 0.000000, 0.000000 }, 
{0.500000, 0.250000, 0.000000 }, 
{0.833333, 0.000000, 0.500000} 
};

Current Code:

pos1 = ArrayFlatten[{{elements, spin}}];
For[
  (i = 1) && (balance = 0) && (store = pos1),
  i < Dimensions[pos1][[1]] + 1,
  i++,
  (For[
     j = 1,
     j < (If[
        balance > 1.01,
        ((Round[xelement[[i]]*Dimensions[PosFCC][[1]]]) + 1),
        (Round[xelement[[i]]*Dimensions[PosFCC][[1]]])
        ]),
     j++,
     store = Insert[store, pos1[[i]], 1]
     ])
   &&
   (If[
     balance > 1.01,
     balance = 0, 
     balance = 
      balance + (xelement[[i]]*Dimensions[PosFCC][[1]] - 
         Round[xelement[[i]]*Dimensions[PosFCC][[1]]])
     ]
    )
  ];

pos2 = RandomSample[store];
pos3 = Transpose[Insert[Transpose[PosFCC], pos2[[All, 1]], 1]];
pos4 = Transpose[Insert[Transpose[pos3], pos2[[All, 2]], 5]];
posd = TableForm[pos4, TableSpacing -> {0, 5}];

Output:

bb     0.           0.25     0.5     Spin=3
dd     0.166667     0.75     0.      Spin=2
dd     0.333333     0.75     0.5     Spin=2
bb     0.666667     0.75     0.5     Spin=3
cc     0.833333     0.5      0.5     Spin=3
ee     0.833333     0.25     0.      Spin=2
aa     0.333333     0.5      0.      Spin=4
dd     0.5          0.75     0.      Spin=2
ee     0.833333     0.75     0.      Spin=2
bb     0.           0.       0.      Spin=3
aa     0.           0.5      0.      Spin=4
ee     0.333333     0.       0.      Spin=2
ee     0.           0.75     0.5     Spin=2
aa     0.5          0.       0.5     Spin=4
bb     0.166667     0.       0.5     Spin=3
bb     0.166667     0.25     0.      Spin=3
aa     0.666667     0.5      0.      Spin=4
cc     0.5          0.5      0.5     Spin=3
aa     0.666667     0.25     0.5     Spin=4
dd     0.166667     0.5      0.5     Spin=2
dd     0.333333     0.25     0.5     Spin=2
cc     0.666667     0.       0.      Spin=3
cc     0.5          0.25     0.      Spin=3
cc     0.833333     0.       0.5     Spin=3
share|improve this question
    
Please provide more information and useful data in the question itself. –  Yves Klett Mar 26 at 19:38
    
Edited with more info + code –  Zhao Mar 27 at 14:14

2 Answers 2

up vote 2 down vote accepted

RandomChoice can take a list of weights, so you can do this:

Join[RandomChoice[xelement -> elements, 24], PosFCC, 2]
share|improve this answer
    
Awesome, thanks! that does exactly what I wanted it to do. –  Zhao Mar 27 at 10:15
    
I realised that RandomChoice randomises the results without considering for limits. I couldn't find a random function that does that so I've updated the post with some code I've written that (I think) does that. –  Zhao Mar 27 at 14:14
elements = Transpose[{{Fe, Mn, Cu, Ni, Tc}}];
xelement = {0.3, 0.3, 0.15, 0.1, 0.15};

Introduce this:

names = {Fe, Mn, Cu, Ni, Tc};

Evaluating

names xelement

then gives

{0.3 Fe, 0.3 Mn, 0.15 Cu, 0.1 Ni, 0.15 Tc}

and

RandomSample[names xelement]

gives

{0.3 Mn, 0.15 Cu, 0.15 Tc, 0.1 Ni, 0.3 Fe}

The last part of your question I cannot understand. Could you reformulate it please?

share|improve this answer
    
Ah, I wanted to take those five items from elements and create up to 24 copies of them but they needed to be weighted according to xelement so they can be combined with the contents in PosFCC. –  Zhao Mar 26 at 17:50
    
@Zhao in the resulting table in your question there are 8 different names of elements. Where do these come from? Could you please provide an example output that corresponds to your definitions? Also I do not see what you mean by "weighted according xelement". I cannot see what this is supposed to mean from your example output. –  Jacob Akkerboom Mar 26 at 18:34
    
@JacobAkkerboom Apologies I suck at explaining >< - and I copy-pasted in from a wrong file. I'm trying to write a script that matches a particular element to a coordinate. Let's say there are 24 coordinates; and that fractionally a:b:c:d:e is 9%:9%:9%:9%:18%. Instead of matching 4 of a, b, c, and d to individual coordinates and e to the final 8 (to a sum of 24), I wanted to generate a list of 24 points from my initial list of a,b,c,d,e and those percentages and then randomly pair them to available coordinates. I know I can use shuffle for the last bit; initial bit's the problem.Eg output @ top –  Zhao Mar 26 at 19:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.