3
$\begingroup$

I need to create an array of data which resembles to something like this

Table[{i, Sin[j^2*i]}, {j, 2000}, {i, 0., Pi, Pi/10000.}]

where each "row" of the array contains a list of tuples for varying values of the 'j' parameter. The time required for this computation can be calculated by the AbsoluteTiming function, giving

{15.1485, Null}

I succeeded in using functional programming at the first level. This speeds things up. For example, the following code does the same thing as the initial one:

Table[{#1, Sin[j^2 #1]} & /@ Range[0, Pi, Pi/10000.], {j, 2000}]

but is 5 times as fast as the original one. AbsoluteTiming returns

{3.71441, Null}

The size of these tables roughly represents the size of the data that I am currently manipulating (lots of it). Since I noticed that Table is not the most "time-efficient" option, I would like to learn how to construct this kind of table with things like pure functions and slots (which I naively assume leads to faster code).

$\endgroup$
6
  • $\begingroup$ Table[{i, Sin[j^2 i]}, {j, 2}, {i, 0., Pi, Pi/100.}]; : Table can take multiple iterators. $\endgroup$
    – Syed
    Commented Sep 17, 2022 at 3:43
  • $\begingroup$ @Syed You are right and I do not know why but I was evaluating a Table with the iterators in the wrong order, which of course was not giving the desired result: Table[{i, Sin[j*i]}, {i, 0., 4 Pi, 4 Pi/100.},{j,2}]. Nevertheless, I have modified the title and updated my question accordingly. $\endgroup$
    – Meclassic
    Commented Sep 17, 2022 at 3:48
  • $\begingroup$ t1 = Chop@Table[{i, Sin[j*i]}, {j, 2}, {i, 0., 4 Pi, 4 Pi/100.}]; and t2 = Chop@ Outer[{#2, Sin[#1 #2]} & , {1, 2}, Range[0., 4 Pi, 4 Pi/100.]]; are almost identical in timing. $\endgroup$
    – Syed
    Commented Sep 17, 2022 at 4:01
  • 1
    $\begingroup$ Table is functional programming. If what you are looking for is to speed up this code, then please edit the question and make that the main topic. $\endgroup$
    – Szabolcs
    Commented Sep 17, 2022 at 7:47
  • $\begingroup$ @Szabolcs I got confused with what functional programming means. You are right, speed is what I am looking for. The question has been edited accordingly. $\endgroup$
    – Meclassic
    Commented Sep 17, 2022 at 14:35

1 Answer 1

6
$\begingroup$

Set

A=N[Range[2000]];
B=N[Range[0,Pi,Pi/10000.]];

I will compare

method1:=Outer[{#2,Sin[#1^2*#2]}&,A,B];
method2:=Transpose[{ConstantArray[B,Length[A]],
                    Sin[Outer[Times,A^2,B]]},{3,1,2}];

To check that they give the same output, run

Max[Abs[Flatten[method1-method2]]]

Timing

RepeatedTiming[method1;]
(* about 27 seconds *)

RepeatedTiming[method2;]
(* about 0.7 seconds *)

So method2 is quite a bit faster. The reason is that it uses packed arrays and certain simple constructs such as Outer[Times,...] that are fast.

Comment. Perhaps there is some room for further improvement, but I would think that one limitation is Sin. Therefore, I would be surprised if there was a solution faster than

temp=RandomReal[{-1,1},Length[A]*Length[B]];
RepeatedTiming[Sin[temp];]
(* about 0.1 seconds *)
$\endgroup$
2
  • 1
    $\begingroup$ Nice answer, but you have a wrong square: A^2. It should only be: A $\endgroup$ Commented Sep 17, 2022 at 7:57
  • $\begingroup$ @DanielHuber Thanks for your feedback. OPs question contains both versions, one without square and one with square, and I thought I take the one with square. $\endgroup$
    – user293787
    Commented Sep 17, 2022 at 8:12

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.