2023-09-04 16:41:07 +02:00
|
|
|
#include "tensoriter.h"
|
2023-05-07 16:58:49 +02:00
|
|
|
|
|
|
|
|
tensoriter_scalar tensoriter_scalar_create(tensor t)
|
|
|
|
|
{
|
2023-09-13 14:12:02 +02:00
|
|
|
/* Creates an iterator over the values of a tensor. If two tensors have the
|
|
|
|
|
* same size the iterator will always iterate over them in the same order.
|
2023-09-03 10:06:46 +02:00
|
|
|
*
|
|
|
|
|
* @param t The tensor to iterate over
|
|
|
|
|
*
|
2023-09-13 14:12:02 +02:00
|
|
|
* @return The iterator, NULL in case of an error
|
2023-09-03 10:06:46 +02:00
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
assert(!tensor_is_empty(t));
|
|
|
|
|
|
|
|
|
|
tensoriter_scalar it = malloc(sizeof(struct _tensor_scalar_iterator));
|
|
|
|
|
if (it == NULL) return NULL;
|
|
|
|
|
|
2023-09-13 14:12:02 +02:00
|
|
|
it->t = t;
|
|
|
|
|
it->index = calloc(sizeof(uint32_t), t->rank);
|
2023-05-07 16:58:49 +02:00
|
|
|
|
|
|
|
|
return it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_destroy(tensoriter_scalar it)
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Destroys an iterator.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to destroy
|
|
|
|
|
*/
|
2023-09-13 14:12:02 +02:00
|
|
|
free(it->index);
|
2023-05-07 16:58:49 +02:00
|
|
|
free(it);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-03 10:06:46 +02:00
|
|
|
bool tensoriter_scalar_next(tensoriter_scalar it)
|
2023-05-07 16:58:49 +02:00
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Checks whether the given iterator has a next value and sets this value
|
|
|
|
|
* as the current value if available. If there is not next value the
|
|
|
|
|
* iterator is destroyed and false is returned.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to evaluate
|
|
|
|
|
*
|
|
|
|
|
* @return true if there is a next value, false otherwise
|
|
|
|
|
*/
|
2023-09-13 14:12:02 +02:00
|
|
|
bool end = true;
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < it->t->rank; i++) {
|
|
|
|
|
if (it->index[i] < it->t->size[i] - 1) {
|
|
|
|
|
(it->index[i])++;
|
|
|
|
|
end = false;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
it->index[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end) {
|
2023-05-07 16:58:49 +02:00
|
|
|
tensoriter_scalar_destroy(it);
|
2023-09-03 10:06:46 +02:00
|
|
|
return false;
|
2023-05-07 16:58:49 +02:00
|
|
|
}
|
|
|
|
|
|
2023-09-03 10:06:46 +02:00
|
|
|
return true;
|
2023-05-07 16:58:49 +02:00
|
|
|
}
|
|
|
|
|
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype tensoriter_scalar_get(tensoriter_scalar it, bool *success)
|
2023-05-07 16:58:49 +02:00
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Gets the current value of the iterator.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
2023-09-13 14:12:02 +02:00
|
|
|
* @param success Is set if not NULL and defines whether the get operation
|
|
|
|
|
* was successful
|
2023-09-03 10:06:46 +02:00
|
|
|
*
|
2023-09-13 14:12:02 +02:00
|
|
|
* @return The current value of the iterator
|
2023-09-03 10:06:46 +02:00
|
|
|
*/
|
2023-09-13 14:12:02 +02:00
|
|
|
return tensor_get(it->t, it->index, success);
|
2023-09-07 21:26:45 +02:00
|
|
|
}
|
|
|
|
|
|
2023-09-13 14:12:02 +02:00
|
|
|
bool tensoriter_scalar_set(tensoriter_scalar it, dtype value)
|
2023-09-07 21:26:45 +02:00
|
|
|
{
|
2023-09-13 14:12:02 +02:00
|
|
|
/* Sets the value of the tensor which the iterator is pointing to at the
|
|
|
|
|
* moment.
|
2023-09-07 21:26:45 +02:00
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param value The value to insert
|
|
|
|
|
*
|
|
|
|
|
*/
|
2023-09-13 14:12:02 +02:00
|
|
|
return tensor_set(it->t, it->index, value);
|
2023-05-07 16:58:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_map(tensoriter_scalar it, dtype (*func)(dtype))
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Replaces every value in an iterator with the result of given function
|
|
|
|
|
* with the old value as a parameter.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param func The map function that is called
|
|
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
do {
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype x = tensoriter_scalar_get(it, NULL);
|
2023-09-07 21:26:45 +02:00
|
|
|
tensoriter_scalar_set(it, func(x));
|
2023-05-07 16:58:49 +02:00
|
|
|
} while(tensoriter_scalar_next(it));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_map_add(tensoriter_scalar it, dtype scalar)
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Adds a fixed scalar value to all the values of the iterator.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param scalar The value to add
|
|
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
do {
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype x = tensoriter_scalar_get(it, NULL);
|
2023-09-07 21:26:45 +02:00
|
|
|
tensoriter_scalar_set(it, DTYPE_ADD(x, scalar));
|
2023-05-07 16:58:49 +02:00
|
|
|
} while(tensoriter_scalar_next(it));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_map_sub(tensoriter_scalar it, dtype scalar)
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Subtracts a fixed scalar value from all the values of the iterator.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param scalar The value to subtract
|
|
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
do {
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype x = tensoriter_scalar_get(it, NULL);
|
2023-09-07 21:26:45 +02:00
|
|
|
tensoriter_scalar_set(it, DTYPE_SUB(x, scalar));
|
2023-05-07 16:58:49 +02:00
|
|
|
} while(tensoriter_scalar_next(it));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_map_mul(tensoriter_scalar it, dtype scalar)
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Multiplies a fixed scalar value with all the values of the iterator.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param scalar The value to multiply
|
|
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
do {
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype x = tensoriter_scalar_get(it, NULL);
|
2023-09-07 21:26:45 +02:00
|
|
|
tensoriter_scalar_set(it, DTYPE_MUL(x, scalar));
|
2023-05-07 16:58:49 +02:00
|
|
|
} while(tensoriter_scalar_next(it));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void tensoriter_scalar_map_div(tensoriter_scalar it, dtype scalar)
|
|
|
|
|
{
|
2023-09-03 10:06:46 +02:00
|
|
|
/* Divides all the values of the iterator by a fixed scalar value.
|
|
|
|
|
*
|
|
|
|
|
* @param it The iterator to operate on
|
|
|
|
|
* @param scalar The value to divide by
|
|
|
|
|
*/
|
2023-05-07 16:58:49 +02:00
|
|
|
do {
|
2023-09-13 14:12:02 +02:00
|
|
|
dtype x = tensoriter_scalar_get(it, NULL);
|
2023-09-07 21:26:45 +02:00
|
|
|
tensoriter_scalar_set(it, DTYPE_DIV(x, scalar));
|
2023-05-07 16:58:49 +02:00
|
|
|
} while(tensoriter_scalar_next(it));
|
|
|
|
|
}
|
|
|
|
|
|