4
$\begingroup$

I wanted a set ("list") of 100 random vectors of dimension 2. I accomplished this already by generating a "list of lists" where the elements of the overall list are 2-dimensional lists consisting of 2 random numbers. Of course, each of these 2-dimensional lists are the vectors, and there are 100 of them. I accomplished this as follows:

vectors = Transpose[{RandomReal[{-1, 1}, 100], RandomReal[{-1, 1}, 100]}]

I know that I can find the norm of each of those vectors by mapping the Norm function onto the overall list, like so:

norms = Map[Norm,vectors]

That is a list of 100 numbers. What I want to do now is multiply each of the vectors by their respective norms. (Note that I am not talking about normalizing them which could've simply been done by coding: Map[Normalize,vectors].)

Essentially, I'd like a one-to-one mapping where element 1 of the list "vectors" is multiplied by element 1 of the list "norms". I'm not sure how to do this. I thought of defining a new function where the argument would be a list (one of those 2-dimensional lists in the list "vectors" above) and the function would multiply the argument by its norm. However, I'm not sure how to program this function or if this is even an efficient way to do it. How could I define this so-called one-to-one mapping?

(My ultimate goal is to plot my resulting vectors, and then run a loop doing this over and over many times.)

$\endgroup$
3
  • $\begingroup$ I wonder if you could do this by using another distribution in the first place, not the uniform distribution. $\endgroup$
    – carlosayam
    Commented Nov 30, 2012 at 23:17
  • $\begingroup$ @caya I actually want to eventually do this for a Normal Distribution, so I could just change the {-1,1} parameter for RandomReal to NormalDistribution[] (not limiting myself to that that small range from -1 to 1 also). Now, the real problem comes when I want to generate Random COMPLEX numbers distributed normally... which seems difficult both algorithmically and mathematically. $\endgroup$ Commented Dec 1, 2012 at 2:25
  • $\begingroup$ hum, @cosmic-strider, according to the wikipedia article for a complex-normal z, |z| follows the Rayleigh distribution and the argument is uniform in [-Pi,Pi]. If wikipedia is right, here you go, both are available in Mathematica and should't be hard :) $\endgroup$
    – carlosayam
    Commented Dec 1, 2012 at 3:39

4 Answers 4

7
$\begingroup$
vectors = RandomReal[{-1, 1}, {100, 2}];
scaled = Map[Norm[#] # &, vectors];

You can use Nest to do it many times:

scaled = Nest[Map[Norm[#] # &, #] &, vectors, 5];
ListPlot[{vectors, scaled}]

Nested

Oh, and to multiply two lists together element-wise just use *

norms = Norm /@ vectors;
norms*vectors == Map[Norm[#] #&, vectors]
(* True *)
$\endgroup$
2
  • $\begingroup$ Thanks a lot! I am probably deviating a bit from my original question, but suppose I instead wanted to generate Random COMPLEX numbers with a normal distribution. I've tried cvectors=RandomComplex[NormalDistribution[],{100,2}], but that gives me vectors with 2 real components. Would you happen to know why this is happening? Is there a way for me to instead generate the real and imaginary parts of the 200 complex numbers independently according to the normal distribution and then combine them? Thanks again for your help earlier!! $\endgroup$ Commented Dec 1, 2012 at 2:31
  • 1
    $\begingroup$ @CosmicStrider yea you can do it like: Complex @@ # & /@ RandomVariate[MultinormalDistribution[{0, 0}, {{1, 0}, {0, 1}}], 10] and in a bunch of other ways :) $\endgroup$
    – ssch
    Commented Dec 1, 2012 at 10:55
10
$\begingroup$

The default multiplication for lists is the pair-wise multiplication you seek. So you just need

 vectors = ...
 norms = Norm /@ vectors (* same as Map *)
 vectorsMultipliedByNorms = vectors norms
$\endgroup$
1
  • $\begingroup$ Many thanks, I can't believe I didn't think of just multiplying the lists! $\endgroup$ Commented Dec 1, 2012 at 2:27
6
$\begingroup$

You could still use Normalize, with a custom norm function:

In[16]:= vectors = RandomReal[{-1, 1}, {100, 2}];

(* ssch's approach *) 
In[17]:= scaled = Map[Norm[#] # &, vectors];

In[18]:= scaled2 = Map[Normalize[#, 1/Norm[#] &] &, vectors];

In[19]:= scaled == scaled2

Out[19]= True
$\endgroup$
1
  • 3
    $\begingroup$ The triangle inequality would like a chat with you ;) $\endgroup$
    – ssch
    Commented Nov 30, 2012 at 22:39
1
$\begingroup$

Also

☺ = #^2 / Normalize @ # &;

Example:

SeedRandom[1]
vectors = RandomReal[{-1, 1}, {100, 2}];
scaled3 = ☺ /@ vectors;
scaled3 == scaled2 == scaled

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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