Message Boards Message Boards

0
|
6584 Views
|
5 Replies
|
1 Total Likes
View groups...
Share
Share this post:

Create a table of unknown size in a Compile function?

Posted 8 years ago

I would like to write a compile function with a Matrix of unknown size(at the moment of the compilation) similar to :

Fx = Compile[{{matrix,_Real},{size,_Integer},Block[{M},
M = Table[{0,0},size];
.... rest of the function ....
];];

The problem is that the compilation failed because the function Table requires a value and not a variable. I absolutely need to initialize this matrix of zeros in the rest of the code, and I want a Compile function in order to save time. Does someone know how to fix this problem?

Thank's in advance Q.A.

POSTED BY: Quentin Ansel
5 Replies
Posted 5 years ago

compiled function For 2D array can be written as

cf2 = Compile[{{size, Integer}, {s, Integer}}, Block[{m}, m = Table[Table[0, {s}], {size}]], RuntimeAttributes -> {Listable}, Parallelization -> True]

For example, cf2[{1, 2, 3, 4}, {4, 5, 6, 2}]= {{{0, 0, 0, 0}}, {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}, {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}, {{0, 0}, {0, 0}, {0, 0}, {0, 0}}}

POSTED BY: Hui Ren

This doesn't fail in any version I try:

cf = Compile[{{size, _Integer}},
  Block[{m},
   m = Table[{0, 0}, {size}]
   ]
  ]

Please describe precisely what the problem is. Give a minimal but complete example.

POSTED BY: Szabolcs Horvát

Hi Marco

the matrix is not big, generally (2*120) and is not sparse at the end of the function. In fact, in the rest of the code I've something like this :

For[k0 = 1, k0 <= nB0, k0++, (* 
  Loop over the different values of B0 *)

  For[k1 = 1, k1 <= nB1, k1++, (* 
    Loop over the different values of B1 *)

    MM = M0;

    For[n = 1, n <= npuls, n++, (* Time evolution for 1 spin*)

     MM = Uevol[0.01, t1, t2, B0[[k0]] + offB0, B1[[k1]] + offB1, 
         u[[n, 1]], u[[n, 2]]].MM;
     Mmean[[n, 1]] = 
      Mmean[[n, 1]] + MM[[2]]*B0distrib[[k0]]*B1distrib[[k1]];
     Mmean[[n, 2]] = 
      Mmean[[n, 2]] + MM[[3]]*B0distrib[[k0]]*B1distrib[[k1]];
     ];

    ];];

where Uevol is a function which gives a matrix. I'm doing very basic operations, sums of products of matrices , and I don't need a formal expression. After that this function will be put inside an objective function minimized by NMinimize. (by the way, apparently NMinimize doesn't like Compile functions as it doesn't work with machine-size real numbers...)

cheers Q.A.

POSTED BY: Quentin Ansel

Hi Quentin,

I cannot really run the code because as you say it is incomplete. One observation is that you use procedural style, like in C or Fortran or so. My guess is that you "speak" one of those. The thing is that in Mathematica there are other styles, such as functional or rule based.

It turns out that functional style is quite optimised and usually faster than procedural. Given your description of the problem, I suspect that the speed gain that you might achieve like that would be substantial. You have three nested loops and getting rid of some/all of them should help.

Cheers,

Marco

POSTED BY: Marco Thiel

Hi Quentin,

this does not answer you question but have you tried optimising that within Mathematica, i.e. without compilation first? Using the Table command is actually quite slow:

Table[0, {40000}, {40000}]; // AbsoluteTiming

takes 43.5 seconds on my computer.

ConstantArray[0, {40000, 40000}]; // AbsoluteTiming

and

Normal[SparseArray[{}, {40000, 40000}]]; // AbsoluteTiming

run about 7.95 seconds. If you can use a SparseArray only it becomes really fast:

SparseArray[{}, {40000, 40000}]; // AbsoluteTiming

Also further calculations on SparseArray are quite fast: 0.000203 seconds.

Cheers,

Marco

POSTED BY: Marco Thiel
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract