algebrite
Version:
Computer Algebra System in Coffeescript
187 lines (129 loc) • 3.33 kB
text/coffeescript
# n is the total number of things on the stack. The first thing on the stack
# is the object to be indexed, followed by the indices themselves.
# called by Eval_index
index_function = (n) ->
i = 0
k = 0
m = 0
ndim = 0
nelem = 0
t = 0
save()
s = tos - n
p1 = stack[s]
ndim = p1.tensor.ndim
m = n - 1
if (m > ndim)
stop("too many indices for tensor")
k = 0
for i in [0...m]
push(stack[s + i + 1])
t = pop_integer()
if (t < 1 || t > p1.tensor.dim[i])
stop("index out of range")
k = k * p1.tensor.dim[i] + t - 1
if (ndim == m)
moveTos tos - n
push(p1.tensor.elem[k])
restore()
return
for i in [m...ndim]
k = k * p1.tensor.dim[i] + 0
nelem = 1
for i in [m...ndim]
nelem *= p1.tensor.dim[i]
p2 = alloc_tensor(nelem)
p2.tensor.ndim = ndim - m
for i in [m...ndim]
p2.tensor.dim[i - m] = p1.tensor.dim[i]
for i in [0...nelem]
p2.tensor.elem[i] = p1.tensor.elem[k + i]
check_tensor_dimensions p1
check_tensor_dimensions p2
moveTos tos - n
push(p2)
restore()
#-----------------------------------------------------------------------------
#
# Input: n Number of args on stack
#
# tos-n Right-hand value
#
# tos-n+1 Left-hand value
#
# tos-n+2 First index
#
# .
# .
# .
#
# tos-1 Last index
#
# Output: Result on stack
#
#-----------------------------------------------------------------------------
#define LVALUE p1
#define RVALUE p2
#define TMP p3
set_component = (n) ->
i = 0
k = 0
m = 0
ndim = 0
t = 0
save()
if (n < 3)
stop("error in indexed assign")
s = tos - n
p2 = stack[s]; # p2 is RVALUE
p1 = stack[s+1]; # p1 is LVALUE
if (!istensor(p1)) # p1 is LVALUE
stop("error in indexed assign")
ndim = p1.tensor.ndim; # p1 is LVALUE
m = n - 2
if (m > ndim)
stop("error in indexed assign")
k = 0
for i in [0...m]
push(stack[ s + i + 2])
t = pop_integer()
if (t < 1 || t > p1.tensor.dim[i]) # p1 is LVALUE
stop("error in indexed assign\n")
k = k * p1.tensor.dim[i] + t - 1
for i in [m...ndim]
k = k * p1.tensor.dim[i] + 0
# copy
p3 = alloc_tensor(p1.tensor.nelem); # p1 is LVALUE # p3 is TMP
p3.tensor.ndim = p1.tensor.ndim; # p1 is LVALUE # p3 is TMP
for i in [0...p1.tensor.ndim]
p3.tensor.dim[i] = p1.tensor.dim[i]; # p1 is LVALUE # p3 is TMP
for i in [0...p1.tensor.nelem]
p3.tensor.elem[i] = p1.tensor.elem[i]; # p1 is LVALUE # p3 is TMP
check_tensor_dimensions p1
check_tensor_dimensions p3
p1 = p3; # p1 is LVALUE # p3 is TMP
if (ndim == m)
if (istensor(p2)) # p2 is RVALUE
stop("error in indexed assign")
p1.tensor.elem[k] = p2; # p1 is LVALUE # p2 is RVALUE
check_tensor_dimensions p1
moveTos tos - n
push(p1); # p1 is LVALUE
restore()
return
# see if the rvalue matches
if (!istensor(p2)) # p2 is RVALUE
stop("error in indexed assign")
if (ndim - m != p2.tensor.ndim) # p2 is RVALUE
stop("error in indexed assign")
for i in [0...p2.tensor.ndim] # p2 is RVALUE
if (p1.tensor.dim[m + i] != p2.tensor.dim[i]) # p1 is LVALUE # p2 is RVALUE
stop("error in indexed assign")
# copy rvalue
for i in [0...p2.tensor.nelem] # p2 is RVALUE
p1.tensor.elem[k + i] = p2.tensor.elem[i]; # p1 is LVALUE # p2 is RVALUE
check_tensor_dimensions p1
check_tensor_dimensions p2
moveTos tos - n
push(p1); # p1 is LVALUE
restore()