opeltre / topos

Statistics and Topology
MIT License
8 stars 0 forks source link

Functor vs. Scalar values #8

Closed opeltre closed 2 years ago

opeltre commented 2 years ago

It would be useful to have a scalar-valued field class with maps to/from the tensor valued fields, i.e.

C[d](K, R)  <-------> C[d](K, R^E)       # where E : K -> Set is the shape functor. 

Right now, one of the most costly operations upon system creation seems to be the following list comprehension: (core/operators.py)

def local_masses(domain):
    indices = [[i, j] for a in domain\
              for i in range(a.begin, a.end)\
              for j in range(a.begin, a.end)]
    ...

Basically we create block diagonal matrices of 1s (sum then extend) when we could reduce this to a scalar valued field (useful for visualisation too). Later composing with an extension matrix would essentially yield the same blocks of 1s but __matmul__ is probably more efficient than this nested list comprehension... :thinking:

N.B: local_masses = S* . S if S denotes the sum from R^E to R.

Useful for operators as well: implement K.zeta, K.delta, ... with scalar values then extend them (allows for concise +-1 representation).

opeltre commented 2 years ago

Creation of normalisation matrix fixed by #9 : local_masses = from_scalar @ from_scalar.T

Domain instance creation now *10 faster

opeltre commented 2 years ago

Problem: from_scalar and to_scalar have different source/target domains - operator degree is not enough

N.B: Only nerve creation is costly in System.__init__ when close=sort=False. The nerve could be passed as argument as well. Probably use another class method not to multiply __init__'s arguments.

Maybe System.closure(...) or System.nerve(...) for the one in use now
And System(Nerve) for the standard initializer

opeltre commented 2 years ago

This works:

from topos.core.operators import to_scalar, from_scalar
A = System(("i:j", "j:k"), shape=3)    # local algebra functor
K = System(("i:j", "j:k"), shape=1)    # local scalar functor

J, S = from_scalar(A[0]), to_scalar(A[0])

u = A[0].ones()
s = K[0].field(S @ u.data)
v = A[0].field(J @ s.data)
opeltre commented 2 years ago

7

Create linear operators with something like:

M = Matrix((tgt, src), mat)

That way it stays close to

M = sparse.matrix((n, m), indices, values)