1

I want to Map something that is depending on an iterator from the outside of e.g. Table into the procedure.

What would be the correct way to do this in Mathematica without evoking error messages.

Here is a simple example of what I am trying to do:

list = {a, b, c};
Map[
  Table[#, {i, Length[list]}] &, 
  { list[[i]] }
]

[Edit]

Since my initial post was a little bit unclear to what I really intend to do, I want to provide another, hopefully clearer example. I am currently experimenting a lot with MMA's Compile function and wondered how one could define a function outside of a compiled function that will be called within the body of the compiled function and may depend on an iteration variable that is counted withing the Compile enviroment. I then stumbled over this thread here which was helpful.

A minimum working example of what I intend to do would be

v[x_] := Part[x, i];

cf = Hold@
     Compile[{{n, _Integer}}, 
      Block[{v, x}, x = Range[n]; Sum[v[x], {i, 1, n}]], 
      CompilationTarget :> "C", RuntimeOptions -> "Speed"] //. 
    DownValues@v // ReleaseHold;

Needs["CompiledFunctionTools`"];
Grid[{{CompilePrint[cf]}}, Frame -> All]

where now the compiled functions compiles through without any calls to MainEvaluate.

On the other hand, as is stated in the linked thread one can typically inline pure external functions into a compiled function by using the option "InlineExternalDefinitions"->True. However, in this case this strategy doesn't seem to be successful. Something like

v = Part[#1, #2] &;

cf2 = Compile[{{n, _Integer}}, 
   Block[{v, x}, x = Range[n]; Sum[v[x, i], {i, 1, n}]], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed", 
   CompilationOptions -> {"InlineExternalDefinitions" -> True}];

Needs["CompiledFunctionTools`"];
Grid[{{CompilePrint[cf2]}}, Frame -> All]

won't compile through without calls to MainEvaluate while something like

g = #^2 &;
cf3 = Compile[{{x, _Real}}, g[x], CompilationTarget -> "C", 
  CompilationOptions -> {"InlineExternalDefinitions" -> True}]

does compile through.

Of course, one can still wonder why I wouldn't inject the definition of v[x] directly into the compiled function. But for my purposes it is more convenient to have one compiled function and change the function v[x] outside of the compiled function where I can now use different function definitions of v[x] for the same compiled function.

NeverMind
  • 1,201
  • 7
  • 9
  • 1
    Given list = {a, b, c}, what outcome would you expect? – Αλέξανδρος Ζεγγ Dec 11 '18 at 13:32
  • {{a,b,c}} in this case, but I want to avoid the error message Part::pspec: Part specification i is neither a machine-sized integer nor a list of machine-sized integers. >>. Tried to use Hold and ReleaseHold but maybe I misplaced it. The list[[i]] shouldn't be evaluated before it is stuffed into the Table. – NeverMind Dec 11 '18 at 13:37
  • The question is more conceptual based, it is not a question of how to get the same answer in a different way. – NeverMind Dec 11 '18 at 13:39
  • Then why is {list} not acceptable? – Αλέξανδρος Ζεγγ Dec 11 '18 at 13:40
  • Because the actual elements depend on the iteration process and cannot be specified a priori. – NeverMind Dec 11 '18 at 13:43
  • 5
    I am sorry but this does not make sense to me. What do you want to Map? Don't you need a nested Table or MapIndexed instead ? – Kuba Dec 11 '18 at 13:45
  • What about {Table[list[[i]], {i, Length[list]}]} - does it work for you? – Kuba Dec 12 '18 at 09:21
  • Please see my [Edit] to the OP and I apologise thoroughly for the confusion I have caused. – NeverMind Dec 12 '18 at 23:05
  • The power of "InlineExternalDefinitions" option is just limted, at least up to now. That's why I prefer With and /. for inlining. BTW the most unreasonable failure I've found: n = 5; test = Compile[{}, Do[i, {i, n}], CompilationOptions -> {"InlineExternalDefinitions" -> True}]; CompilePrint[test]. – xzczd Dec 13 '18 at 10:38
  • Yeah, since it can be so cumbersome I think I will check out plain C over Christmas even though I like MMA. @xzczd: Yeah need to localise the n variable then it is alright. This is what I learned about Compile, no matter what you do always localise your variables. – NeverMind Dec 13 '18 at 10:57
  • The issue in my example is not localization, the issue is, n should be inlined by "InlineExternalDefinitions" in principle. Check the following example: n = 5; test2 = Compile[{}, Do[i + n, {i, 8}], CompilationOptions -> {"InlineExternalDefinitions" -> True}]; CompilePrint[test2] – xzczd Dec 13 '18 at 11:03
  • Ok, now I got your point. Nevertheless, localisation resolves the first case for some reason and doesn't harm the second one, though the behaviour in the first case is weird then I agree. "InlineExternalDefinitions" is then certainly not behaving as it is supposed to according to the documentation. – NeverMind Dec 13 '18 at 11:24

1 Answers1

2

Maybe use Unevaluated or pass a function:

Map[Table[#, {i, Length[list]}] &, {Unevaluated[list[[i]]]}]
Map[Table[#[i], {i, Length[list]}] &, {list[[#]] &}]
Coolwater
  • 20,257
  • 3
  • 35
  • 64