Question: confused about piecewise()/levels of evaluation

Unfortunately piecewise() is a builtin so I can't see the library code.

I'm trying to construct a sequence of arguments to piecewise() programmatically, and to assign the result to a function but I just can't seem to set it up correctly.

I have a 10x18 matrix, each row of which will be used to define a piecewise linear function, so the columns in a row define the endpoint values of each line segment.

Essentially what I'm trying to do is the following (giving some Maple pseudo-code which doesn't work, but hopefully will get the idea across):

# establish a sequence of arguments to piecewise(), constructed from matrix M

# assume i, the row number, has already been assigned; treating column 0 as containing all zeroes is arbitrary

S := NULL;

for j to 18 do

    S := S, j-1 < x <= j, (j - x) * `if`(j = 1, 0, M[i,j-1]) + (x - j + 1) * M[i,j];

end do;

# use piecewise() on S to create a case-defined expression, from it construct a function f[i] defined on the real closed interval [1,18], such that for any integer j from 1 to 18, (f[i])(j) = M[i,j]

f[i] := y -> subs(x = y, piecewise(S));

 

I'd appreciate seeing either simply a method that works (using loops for example) or a more elegant solution (using seq() for example).

My problem with the seq() approach is that I don't know how to stop seq() from flattening sequences given as arguments:

seq((j-1 < x <= j, (j - x) * `if`(j = 1, 0, M[i,j-1]) + (x - j + 1) * M[i,j]), j = 1..18)

gives an error. In other words, I want to use seq() in the following way: seq( ( g(j), h(j) ), j = 1..18) ; so that I get a sequence of 36 terms, (g(1), h(1), ..., g(18), h(18)), but as written, the seq() function gets three arguments, with j = 1..18 causing an error in position 3.

But if I use a loop as above, I run into problems with evaluation of the name S. If I put the code above in a loop iterating over i, all functions f[1] to f[10] get the same S, namely the last value S is assigned - that I understand. I could assign S[1] to S[10], but that seems silly: S is just taking on the role of a temporary variable in which to construct the arguments to piecewise(). I don't really want to use an S at all, and I'm sure that I don't need it.

I've tried variations on the above themes, using eval(), unevaluation quotes, proc() instead of arrow notation, but I am confused.

I know that I should be able to construct all ten functions f[1] to f[10] at once using something like assign() containing two calls to seq(), nested, one for i=1..10 and the other for j=1..18, but again, can't figure out the correct way of writing it.

So I've turned to the experts for help!

Please Wait...