5
$\begingroup$

I have a the following code:

data = RandomReal[1, {13000, 3}];

x = 1;
y = 2.3;
z = 0.7;

data[[All, 1]] = data[[All, 1]]*x; 
data[[All, 2]] = data[[All, 2]]*y; 
data[[All, 3]] = data[[All, 3]]*z;

How would you solve the recalculation of data?

$\endgroup$
  • 1
    $\begingroup$ What do you mean by "solve the recalculation"? $\endgroup$ – swish Oct 11 '17 at 13:35
  • 1
    $\begingroup$ Maybe, you would like to know about TimesBy (*=)? Example: data[[All, 1]] *= x; $\endgroup$ – Henrik Schumacher Oct 11 '17 at 13:40
7
$\begingroup$

Convert your vector to a diagonal matrix, and then use Dot:

data = RandomReal[1,{13000,3}];
data1 = data . DiagonalMatrix[{x, y, z}]; //RepeatedTiming

{0.000051, Null}

Another very fast approach suggested by @LLlAMnYP (making sure to pack the vector first):

m = Developer`ToPackedArray @ N @ {x, y, z};
data2 = Transpose[data] m //Transpose; //RepeatedTiming

{0.000085, Null}

Compare with your approach:

data[[All, 1]] = data[[All, 1]] x;
data[[All, 2]] = data[[All, 2]] y;
data[[All, 3]] = data[[All, 3]] z;

data == data1 == data2

True

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ Transpose[data] {x,y,z} // Transpose is competitive too, especially if instead of {x,y,z} we have a packed array. $\endgroup$ – LLlAMnYP Oct 11 '17 at 14:11
  • $\begingroup$ Thank you and also to @LLlAMnYP for the solutions ... great. $\endgroup$ – lio Oct 11 '17 at 14:47
3
$\begingroup$

Maybe you would like to get to know TimesBy, a.k.a. *=.

data0 = RandomReal[1, {1300000, 3}];
x = 1;
y = 2.3;
z = 0.7;

The original approach:

data = data0;
AbsoluteTiming[
 data[[All, 1]] = data[[All, 1]]*x;
 data[[All, 2]] = data[[All, 2]]*y;
 data[[All, 3]] = data[[All, 3]]*z;
 ]
data1 = data;

(* {0.097083, Null} *)

A naive approach with TimesBy:

data = data0;
AbsoluteTiming[
 data[[All, 1]] *= x;
 data[[All, 2]] *= y;
 data[[All, 3]] *= z;
 ]
data2 = data;

(* {0.104508, Null} *)

Seemingly, this does not help. Hence another approach with TimesBy:

data = data0;
AbsoluteTiming[
 data *= ConstantArray[Developer`ToPackedArray[N[{x, y, z}]], Length[data]];
 ]
data3 = data;

(* {0.021616, Null} *)

... and a check for correct results:

data1 == data2
data1 == data3

(* True *)
(* True *)
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Thank you vey much for you help. $\endgroup$ – lio Oct 11 '17 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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