1

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?

Quark Soup
  • 1,610
  • 9
  • 14

2 Answers2

6

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]
Henrik Schumacher
  • 106,770
  • 7
  • 179
  • 309
  • That's a useful trick (the Indexed). I never knew that one. – b3m2a1 Sep 05 '18 at 06:55
  • @b3m2a1 Yeah, me neither. =D – Henrik Schumacher Sep 05 '18 at 09:29
  • 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). – NeverMind Oct 12 '18 at 20:37
  • @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. – Henrik Schumacher Oct 12 '18 at 20:41
  • @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. – NeverMind Oct 12 '18 at 20:46
  • @DisplayName Towards Szabolcs comment: It depends. If you can build the array directly with Table or by linear algebra operations, you don't have to preallocate. But some algorithms require an interative scheme to build the matrix, so sometimes, yes, preallocation is necessary. – Henrik Schumacher Oct 12 '18 at 20:54
  • @DisplayName And I learned these undocumented things on this site. E.g., this post is very, very useful. – Henrik Schumacher Oct 12 '18 at 20:56
  • @HenrikSchumacher: Yes, this is what I meant pre-allocation is necessary if I have an iteration involved. Ok, so at least when it comes to this I am not wasting computation time. I just wonder by whom the information on undocumented functions was spread for the first time and for what purpose there are undocumented functions at all. But thank you for the link I will certainly take a look at it! – NeverMind Oct 12 '18 at 20:58
2

How about this

dim = 3;
Array[X, dim]