Bug SS-2319
1 vote

vectorize() must not alter inner function logic

Created by Mike Kaganski on 4/17/2016 2:18 PM Last Updated by Mike Kaganski on 4/22/2016 6:52 AM
Logged: 0   (hrs)


vectorize() should only operate on its direct operands. If it is applied to a function f(), it must alter only arguments to that function: all arguments to f() that are matrices must not be actually passed to f(); instead f() must be evaluated separately for each nth element of those arguments.

But this doesn't mean that vectorize() may alter the inner structure of f(). Each invocation of f() inside vectorize() for an argument's element must be exactly the same as if f() would be explicitly called for that element without vectorize(), regardless of optimization mode. So, vectorize() must not descend inside functions regardless if they themselves contain matrices or not. Failing to do so is disastrous for calculations. It leads to unpredictable results; it doesn't allow for some uses of vectorize(); it makes built-in and plugin functions behave differently than defined in sheet (thus making user functions a second-class citizens).

So, vectorize() must not perform any optimizations on its arguments before deciding which resulting items will be subject to vectorizing; instead, it must decide which names (items) are subject to vectorizing, before optimizing arguments, and do further optimizations while substituting those items with dummy (unused) names, so that it may later safely iterate the optimized results, substituting elements for dummy parameters back.

Attached is the demonstration of the problem.

    Mike Kaganski (Sunday, April 17, 2016 6:01 PM) #

Basically, I suppose, it should do following:

  1. Make a tree of its unoptimized argument that would contain items (numbers, matrices, variables, functions).
  2. Get types of arguments of functions (primitive tokens, variables) - here it may perform optimization and/or evaluation (as required) of those items only.
  3. For those functions that have their arguments only scalar, get type of results as arguments to higher-level functions (again, evaluate and optimize them only). Repeat this step until all arguments are either known types or are results of functions with vector arguments.
  4. Decide which items will be vectorized (those that type is matrix). Check that their dimensions are equal. Only do first-level vectorization (matrix of matrices will be iterated for its matrices, not for their elements).
  5. Substitute vectorizing items with dummy variables and perform full optimization of result.
  6. With optimized result, perform iterations with dummy variables substituted with corresponding items' elements.