| 559 | |
| 560 | PG_FUNCTION_INFO_V1(l2_normalize); |
| 561 | Datum l2_normalize(PG_FUNCTION_ARGS) |
| 562 | { |
| 563 | FloatVector *a = PG_GETARG_FLOATVECTOR_P(0); |
| 564 | const float *ax = a->x; |
| 565 | double norm = -NEGATIVE_INNER_PRODUCT_DIST(ax, ax, a->dim); |
| 566 | norm = sqrt(norm); |
| 567 | |
| 568 | FloatVector *result = InitFloatVector(a->dim); |
| 569 | if (norm <= 0) { /* Return zero vector for zero norm */ |
| 570 | PG_RETURN_POINTER(result); |
| 571 | } |
| 572 | |
| 573 | float *rx = result->x; |
| 574 | if (norm == 1) { |
| 575 | memcpy(rx, ax, a->dim * sizeof(float)); |
| 576 | PG_RETURN_POINTER(result); |
| 577 | } |
| 578 | |
| 579 | for (int16 i = 0; i < a->dim; ++i) { |
| 580 | rx[i] = ax[i] / norm; |
| 581 | } |
| 582 | for (int16 i = 0; i < a->dim; ++i) { |
| 583 | if (isinf(rx[i])) { |
| 584 | float_overflow_error(); |
| 585 | } |
| 586 | } |
| 587 | PG_RETURN_POINTER(result); |
| 588 | } |
| 589 | |
| 590 | void floatvector_normalize(float *ax, int16 dim) |
| 591 | { |
nothing calls this directly
no test coverage detected