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 have an $M \times K$ matrix $C$ and a length $K$ vector $v$. I want to form the $M \times K$ matrix $S$ where $s_{ij} = C_{ij}/v_j$. To do this in numpy I simply divide the two objects like this

  S = C/v

but that fails in Mathematica.

What is the most efficient way to do this?

share|improve this question
    
S=#/v & @@@ C; Best regards to Mr.Wizard! –  faleichik Mar 11 '12 at 20:09
4  
@faleichik Shouldn't that be #/v & /@ C? –  Heike Mar 11 '12 at 20:33
5  
One important thing to keep in mind when you're coming from MATLAB is that arrays in Mathematica are general $n$-dimensional tensors, while MATLAB works with matrices only. This has a significant influence on how operations work in the two systems. In Mathematica there is no such thing as a row vector and columns vector: a vector is a strictly 1D structure and both the product vec.mat and mat.vec work. (You can of course have an $1\times n$ or $n\times 1$ matrix.) Operations between $m \times k$ matrices and $m$-length vectors do work automatically, but not with $k$-length vectors. –  Szabolcs Mar 11 '12 at 20:40
4  
Another advice: don't use identifiers with capital names in Mathematica to avoid conflicts with builtins and packages. Both C and K are built-in symbols, and assigning to either of them will break the system in subtle ways (for those who wonder, yes: even assigning to K breaks it, I have seen examples). –  Szabolcs Mar 11 '12 at 20:41
    
@Heike yes, it definitely should. I promise to never post anything without verifying it. –  faleichik Mar 12 '12 at 4:19
add comment

4 Answers

up vote 13 down vote accepted

The problem is that Mathematica wants to match up $v$ with the rows of $C$. In order to get what you want, you can do:

S=Transpose[Transpose[C]/v]
share|improve this answer
    
Here's what it should look like :Mathematica graphics –  CHM Mar 11 '12 at 20:53
    
Perfect, thank you! –  Brian B Mar 12 '12 at 2:06
add comment

I'll construct a $5\times3$ matrix of ones to use for illustration purposes:

m = ConstantArray[1,{5, 3}]

enter image description here

We can multiply each row by the corresponding element from a vector using simple multiplication:

m*{1,2,3,4,5}

enter image description here

Multiplying each column by the corresponding element from a vector is a bit more complicated. There are several possibilities, some of which are already covered by others, but here's one I like for being conceptually simple in that it doesn't use Transpose or explicit iteration (Table, Map, etc...)

ScalingTransform[{1,2,3}][m]

enter image description here

This could also be written using postfix notation m // ScalingTransform[{1,2,3}] if desired.


After looking at Artes's timing comparison, the ScalingTransform approach is quite slow, since it's constructing a large dense matrix. We can use the same underlying idea using a specially constructed SparseArray, however, which is much faster:

m.SparseArray[Band[{1, 1}] -> {1,2,3,4,5}]

Cc = RandomReal[{100}, {700, 900}];
v = RandomReal[{100}, {900}];

ScalingTransform[1/v][Cc]; // AbsoluteTiming

(* ==> {16.333062, Null} *)

Cc.SparseArray[Band[{1, 1}] -> 1/v]; // AbsoluteTiming

(* ==> {0.021044, Null} *)
share|improve this answer
2  
One thing I always wondered: In Mathematica, is Transpose an $O(1)$ operation or is it proportional to the number of elements? (Does it actually copy stuff in memory or does it just flip a switch on how to interpret the in-memory data?) –  Szabolcs Mar 11 '12 at 20:43
2  
@Szabolcs I believe Transpose actually copies stuff in memory, which is backed up by looking at how long it takes to transpose matrices of various (large-ish) sizes. –  Brett Champion Mar 11 '12 at 20:54
add comment

You can get results roughly equally fast to sblom's double-Transpose approach using the generalised version of Inner.

Inner[Divide, matrix, vector, List]

Timing tests
Set up some example data:

ci = RandomInteger[{0, 100}, {20, 3}];
cr = RandomReal[{0., 100.}, {20, 3}];
vi = {3, 2, 1};
vr = {3., 2., 1.};

Division

In[38]:= Do[Transpose[Transpose[ci]/vi];, {1000}] // Timing (*sblom*)

Out[38]= {0.047, Null}

In[39]:= Do[#/vi & /@ ci;, {1000}] // Timing (* faleichik/Heike in comments*)

Out[39]= {0.172, Null}

In[56]:= Do[Inner[Divide, ci, vi, List];, {1000}] // Timing (* me *)

Out[56]= {0.047, Null}

In[40]:= Do[ScalingTransform[1/vi][ci];, {1000}] // Timing (* Brett *)

Out[40]= {0.39, Null}

(* as before but for real numbers *)

In[41]:= Do[Transpose[Transpose[cr]/vr];, {1000}] // Timing  

Out[41]= {0.016, Null}

In[42]:= Do[#/vr & /@ cr;, {1000}] // Timing

Out[42]= {0.109, Null}

In[57]:= Do[Inner[Divide, cr, vr, List];, {1000}] // Timing

Out[57]= {0.031, Null}

In[43]:= Do[ScalingTransform[1/vr][cr];, {1000}] // Timing

Out[43]= {0.36, Null}

Multiplication
As an aside, because of the way Divide works internally, if you are dividing through by the same vector a lot, it makes some sense to create a vector that is 1./thefirstvector and multiply through with that. The effect is more noticeable if you have integer data.

ivi = 1/vi;
ivr = 1./vr;


In[82]:= Do[Transpose[Transpose[ci]*ivi];, {1000}] // Timing 
Out[82]= {0.031, Null}

In[83]:= Do[#*ivi & /@ ci;, {1000}] // Timing
Out[83]= {0.125, Null}

In[84]:= Do[Inner[Times, ci, ivi, List];, {1000}] // Timing

Out[84]= {0.031, Null}


In[85]:= Do[ScalingTransform[ivi][ci];, {1000}] // Timing

Out[85]= {0.375, Null}

In[86]:= Do[Transpose[Transpose[cr]*ivr];, {1000}] // Timing

Out[86]= {0.016, Null}

In[87]:= Do[#*ivr & /@ cr;, {1000}] // Timing

Out[87]= {0.063, Null}

In[88]:= Do[Inner[Times, cr, ivr, List];, {1000}] // Timing

Out[88]= {0.031, Null}


In[89]:= Do[ScalingTransform[ivr][cr];, {1000}] // Timing

Out[89]= {0.343, Null}
share|improve this answer
    
See somewhat related question on StackOverflow: stackoverflow.com/a/7663695/758485 –  Verbeia Mar 12 '12 at 3:14
add comment

Not the most efficient way but sufficiently instructive can be for example this:

Cc = RandomInteger[{1, 10}, {3, 4}]
v = RandomInteger[{1, 10}, {4}]
S = Table[Cc[[i, j]]/v[[j]], {i, 1, 3}, {j, 1, 4}]
  {{7, 9, 6, 4}, {2, 3, 5, 8}, {6, 1, 7, 4}} 
  {2, 2, 4, 3}
  {{7/2, 9/2, 3/2, 4/3}, {1, 3/2, 5/4, 8/3}, {3, 1/2, 7/4, 4/3}} 

This hasn't been mentioned, it's nice but not very efficient :

Inner[Divide, Cc, v, List]

Let's compare performances of various methods :

Cc = RandomReal[{100}, {700, 900}];
v  = RandomReal[{100}, {900}];

S1 = Table[ Cc[[i, j]] / v[[j]], {i, 1, 700}, {j, 1, 900}]; // AbsoluteTiming
S2 = Inner[Divide, Cc, v, List]; // AbsoluteTiming
S3 = #/v & /@ Cc; // AbsoluteTiming
S4 = Transpose[Transpose[Cc]/v]; // AbsoluteTiming
{0.1080000, Null} 
{0.4310000, Null}
{0.0180000, Null} 
{0.0260000, Null}
S1 == S2 == S3 == S4
True

It appears the method based on Map is the best with respect to performance issues.

share|improve this answer
    
+1 for use of Inner –  Mr.Wizard Mar 12 '12 at 5:12
    
@Mr.Wizard Thank You ! I should add that Inner[ Times, Cc, 1/v, List] is a bit more efficient that Inner[Divide, Cc, v, List]. –  Artes Mar 12 '12 at 10:02
add comment

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.