1
$\begingroup$

I'm trying to follow the code posted by a user on Stack Exchange and I'm having trouble with an allocation of a matrix. The code is:

dim = 3;
XX = Table[X[[i]], {i, dim}];

and it's supposed to create an array of:

{X[[1]], X[[2]], X[[3]]}

And it does, but I get the following warnings:

Part::partd: Part specification X[[1]] is longer than depth of object. >>
Part::partd: Part specification X[[2]] is longer than depth of object. >>
Part::partd: Part specification X[[3]] is longer than depth of object. >>
General::stop: Further output of Part::partd will be suppressed during this calculation. >>

What's the proper way to allocate this matrix without the warnings?

$\endgroup$
2
  • 1
    $\begingroup$ If X has no parts, you can not use Part on it. $\endgroup$ Commented Sep 5, 2018 at 2:55
  • 2
    $\begingroup$ In Mathematica there is almost never a need to pre-allocate an array. What are you actually trying to do? $\endgroup$
    – Szabolcs
    Commented Sep 5, 2018 at 7:57

2 Answers 2

6
$\begingroup$

Not sure for what you are going to use this for, but I use things like XX = Table[X[[i]], {i, dim}]; frequently for symbolic preprocessing code for Compile. In that case, Array[X, dim] won't work.

You can ignore the warning with XX = Quiet[Table[X[[i]], {i, dim}]]; or you can use XX = Table[Indexed[X,i], {i, dim}]; instead.

As I found out only recently, Compile is clever enough to substitute Indexed by Part as can be seen in the following example:

dim = 3;
XX = Table[Indexed[X, i], {i, dim}];
cDf = With[{code = D[Sin[XX[[1]]] + XX[[2]]^3, {XX, 1}]},
   Compile[{{X, _Real, 1}}, code, CompilationTarget -> "C"]
   ];
CompiledFunctionTools`CompilePrint[cDf]
$\endgroup$
8
  • $\begingroup$ That's a useful trick (the Indexed). I never knew that one. $\endgroup$
    – b3m2a1
    Commented Sep 5, 2018 at 6:55
  • $\begingroup$ @b3m2a1 Yeah, me neither. =D $\endgroup$ Commented Sep 5, 2018 at 9:29
  • $\begingroup$ Stumbled over your post @HenrikSchumacher and tried your neat example on MM9. Unfortunately, the CompilePrint[] gives me MainEvaluate[] calls, which are not supposed to be there in your example I guess. When I use compile and need to pre-allocate an array, I create a zero-array. However, it's not symbolic then. I am just currently looking for the fastest way to do this (currently I simply call Table[] within compile). $\endgroup$
    – NeverMind
    Commented Oct 12, 2018 at 20:37
  • $\begingroup$ @DisplayName The trick about Indexed is pretty new and won't work in older version (version 9 is actually not that fresh any more). You might want to try the undocumented Compile`GetElement instead of Indexed (will also be quite a bit fast if also the option RuntimeOptions -> "Speed" is added). Or you can use the good old Part instead of Indexed and neglect the Part::partd messages by wrapping everything with Quiet. $\endgroup$ Commented Oct 12, 2018 at 20:41
  • $\begingroup$ @HenrikSchumacher: Ok, that explains it. Yeah, you actually taught me to use Compile`GetElement, since then I stick to this one. This is a undocumented function, right? Where do you learn these kind of things? Is there a list somewhere? When using Compile[] you always need to pre-allocate your arrays right, there is no way to circumvent that if I use a iteration to fill e.g. a vector within Compile, is there? Just asking because of @Szabolcs comment further up on this page. $\endgroup$
    – NeverMind
    Commented Oct 12, 2018 at 20:46
2
$\begingroup$

How about this

dim = 3;
Array[X, dim]
$\endgroup$

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