median, mean and argsort added for vector class

This commit is contained in:
Nicolas Kruse 2025-11-27 17:21:33 +01:00
parent 054ce6d507
commit a8eeea874b
2 changed files with 86 additions and 7 deletions

64
src/copapy/filters.py Normal file
View File

@ -0,0 +1,64 @@
from . import variable, vector
from ._basic_types import iif, unifloat, TNum
from typing import Any, Iterable
def homogenize_vector(input_values: Iterable[TNum | variable[TNum]]) -> Iterable[TNum] | Iterable[variable[TNum]]:
input_list = list(input_values)
if any(isinstance(val, variable) for val in input_list):
return (v if isinstance(v, variable) else variable(v) for v in input_list)
else:
return (v for v in input_list if not isinstance(v, variable))
def _inv_argsort(input_vector: vector[TNum]) -> vector[int]:
positions = (sum((v1 > v2) for v2 in input_vector) for v1 in input_vector)
return vector(positions)
def argsort(input_vector: vector[TNum]) -> vector[int]:
"""
Perform an indirect sort. It returns an array of indices that index data
in sorted order.
Args:
input_vector: The input vector containing numerical values.
Returns:
Index array.
"""
return _inv_argsort(_inv_argsort(input_vector))
def median(input_vector: vector[TNum]) -> TNum | variable[TNum]:
"""
Applies a median filter to the input vector and returns the median as a unifloat.
Args:
input_vector: The input vector containing numerical values.
Returns:
The median value of the input vector.
"""
vec = input_vector
ret = vec[0]
for v1 in vec:
n2 = len(vec) // 2 + 1
lt = sum(v1 < v2 for v2 in vec)
gt = sum(v1 > v2 for v2 in vec)
ret = iif((lt < n2) & (gt < n2), v1, ret)
return ret
def mean(input_vector: vector[Any]) -> unifloat:
"""
Applies a mean filter to the input vector and returns the mean as a unifloat.
Args:
input_vector (vector): The input vector containing numerical values.
Returns:
unifloat: The mean value of the input vector.
"""
return input_vector.sum() / len(input_vector)

View File

@ -1,7 +1,7 @@
import math import math
import copapy as cp import copapy as cp
import pytest import pytest
from copapy import filters
def test_vectors_init(): def test_vectors_init():
tt1 = cp.vector(range(3)) + cp.vector([1.1, 2.2, 3.3]) tt1 = cp.vector(range(3)) + cp.vector([1.1, 2.2, 3.3])
@ -95,12 +95,27 @@ def test_non_compiled_vector_operations():
assert rotated.values[2] == pytest.approx(3.0, abs=1e-6) # pyright: ignore[reportUnknownMemberType] assert rotated.values[2] == pytest.approx(3.0, abs=1e-6) # pyright: ignore[reportUnknownMemberType]
if __name__ == "__main__": def test_sort_vector():
test_vectors_init() vlist = [50, 21, 20, 10, 22, 1, 80, 70, 90]
test_compiled_vectors() t1 = cp.vector(cp.variable(v) for v in vlist)
test_vector_operations() #t1 = cp.vector(v for v in vlist)
print('Finished!')
t2 = filters.median(t1)
tg = cp.Target()
tg.compile(t2)
tg.run()
result = tg.read_value(t2)
ref = sorted(vlist)[len(vlist) // 2]
print(sorted(vlist))
assert ref == result
if __name__ == "__main__": if __name__ == "__main__":
test_compiled_vectors() #test_vectors_init()
#test_compiled_vectors()
test_sort_vector()
print('Finished!') print('Finished!')