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$

closed as unclear what you're asking by Szabolcs, José Antonio Díaz Navas, bbgodfrey, Bob Hanlon, gwr Sep 11 '18 at 10:55

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    $\begingroup$ If X has no parts, you can not use Part on it. $\endgroup$ – Αλέξανδρος Ζεγγ Sep 5 '18 at 2:55
  • 1
    $\begingroup$ In Mathematica there is almost never a need to pre-allocate an array. What are you actually trying to do? $\endgroup$ – Szabolcs Sep 5 '18 at 7:57
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$
  • $\begingroup$ That's a useful trick (the Indexed). I never knew that one. $\endgroup$ – b3m2a1 Sep 5 '18 at 6:55
  • $\begingroup$ @b3m2a1 Yeah, me neither. =D $\endgroup$ – Henrik Schumacher Sep 5 '18 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$ – Display Name Oct 12 '18 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$ – Henrik Schumacher Oct 12 '18 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$ – Display Name Oct 12 '18 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.