# Felix sparse field idea
## Case: Current implementation (assumes `s` is pre-shifted)
- sparse field `s: Field[V,V2E]`
- `e: Field[E]`
```python=
def sten(e, s):
return reduce(dot, 0.0)(s, shift(V2E)(e))
```
### In field view
```python=
def sten(e: Field[Edge], s: Field[Vertex, V2EDim]) -> Field[Vertex]
return neighbor_sum(e(V2E) * s, axis=V2EDim)
```
## New idea
- new dimension (location type) let's call it `VE` with points living on the connection between Vertex and Edge neighbors (no order, it's not V2E or E2V)
- sparse field `s: Field[VE]`
- connectivity mapping from VE to edge location `V2VE`
```python=
def sten(e, s):
return reduce(dot, 0.0)(shift(V2VE)(s), shift(V2E)(e))
```
### In field view
`V2VE` maps from `VE` to `Vertex, V2EDim`
`V2E` maps from `Edge` to `Vertex, V2EDim`
```python=
def sten(e: Field[Edge], s: Field[VE]) -> Field[Vertex]
return neighbor_sum(e(V2E) * s(V2VE), axis=V2EDim)
```
#### Note
There is also a (ineffecient) mapping `E2VE`, which maps from `VE` to `Edge, E2VDim`. Inefficient because neighbors are not ordered in the `Field[VE]`, if they were ordered for `V2VE`.
### Picture
```
(0v) ---0e--- (1v) ---1e--- (2v)
0ve 1ve 2ve 3ve
```
```
V2VE_tbl = [[-1, 0], [1, 2], [3, -1]]
E2VE_tbl = [[0, 1], [2,3]]
```
## Notes
CE: C2CE
EC: E2CE
### Other ideas
```python=
# e, s are iterator pointing to Vertex
shift(V2E_,0)(s) # is now pointing to (Vertex, V2EDim)
return shift(V2E_,0)(s)*shift(V2E,0)(e)+...
```
```python=
def sten(e0: Field[Edge, MyDim], e1: Field[Edge, MyDim]) -> Field[Vertex]
return sum(e1(offset) * e1(offset) for offset in V2E)
return e1(V2E)[V2E(0)] * e1(V2E[0]) + e1(V2E[1] * e2(V2E[1] + ...))
```