Skip to content

Commit

Permalink
FEAT: Add functionality to find maximum and minimum values in a vector
Browse files Browse the repository at this point in the history
  • Loading branch information
Oldes committed Dec 11, 2024
1 parent af420cd commit 2199450
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
118 changes: 118 additions & 0 deletions src/core/t-vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,116 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
}
}

void Find_Minimum_Of_Vector(REBSER *vect, REBVAL *ret) {
REBLEN len, n;
REBYTE *data;

len = SERIES_TAIL(vect);

if (len == 0) {
SET_NONE(ret);
return;
}

#define FIND_MIN_INT(type) { \
type *typed_data = (type *)data; \
type min_value = typed_data[0]; \
for (REBLEN i = 1; i < len; i++) { \
if (typed_data[i] < min_value) \
min_value = typed_data[i]; \
} \
SET_INTEGER(ret, min_value); \
return; \
}

#define FIND_MIN_DEC(type) { \
type *typed_data = (type *)data; \
type min_value = typed_data[0]; \
for (REBLEN i = 1; i < len; i++) { \
if (typed_data[i] < min_value) \
min_value = typed_data[i]; \
} \
SET_DECIMAL(ret, min_value); \
return; \
}

data = SERIES_DATA(vect);

switch (VECT_TYPE(vect)) {
case VTSI08: FIND_MIN_INT(i8); break;
case VTSI16: FIND_MIN_INT(i16); break;
case VTSI32: FIND_MIN_INT(i32); break;
case VTSI64: FIND_MIN_INT(i64); break;
case VTUI08: FIND_MIN_INT(u8); break;
case VTUI16: FIND_MIN_INT(u16); break;
case VTUI32: FIND_MIN_INT(u32); break;
case VTUI64: FIND_MIN_INT(u64); break;
case VTSF32: FIND_MIN_DEC(float); break;
case VTSF64: FIND_MIN_DEC(double); break;
default:
SET_NONE(ret); // Handle unknown types
return;
}

#undef FIND_MIN_INT
#undef FIND_MIN_DEC
}

void Find_Maximum_Of_Vector(REBSER *vect, REBVAL *ret) {
REBLEN len, n;
REBYTE *data;

len = SERIES_TAIL(vect);

if (len == 0) {
SET_NONE(ret);
return;
}

#define FIND_MAX_INT(type) { \
type *typed_data = (type *)data; \
type max_value = typed_data[0]; \
for (REBLEN i = 1; i < len; i++) { \
if (typed_data[i] > max_value) \
max_value = typed_data[i]; \
} \
SET_INTEGER(ret, max_value); \
return; \
}

#define FIND_MAX_DEC(type) { \
type *typed_data = (type *)data; \
type max_value = typed_data[0]; \
for (REBLEN i = 1; i < len; i++) { \
if (typed_data[i] > max_value) \
max_value = typed_data[i]; \
} \
SET_DECIMAL(ret, max_value); \
return; \
}

data = SERIES_DATA(vect);

switch (VECT_TYPE(vect)) {
case VTSI08: FIND_MAX_INT(i8); break;
case VTSI16: FIND_MAX_INT(i16); break;
case VTSI32: FIND_MAX_INT(i32); break;
case VTSI64: FIND_MAX_INT(i64); break;
case VTUI08: FIND_MAX_INT(u8); break;
case VTUI16: FIND_MAX_INT(u16); break;
case VTUI32: FIND_MAX_INT(u32); break;
case VTUI64: FIND_MAX_INT(u64); break;
case VTSF32: FIND_MAX_DEC(float); break;
case VTSF64: FIND_MAX_DEC(double); break;
default:
SET_NONE(ret); // Handle unknown types
return;
}

#undef FIND_MAX_INT
#undef FIND_MAX_DEC
}


/***********************************************************************
**
Expand All @@ -190,6 +300,14 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk)
case SYM_SIGNED:
SET_LOGIC(ret, !(VECT_TYPE(vect) >= VTUI08 && VECT_TYPE(vect) <= VTUI64));
break;
case SYM_MIN:
case SYM_MINIMUM:
Find_Minimum_Of_Vector(vect, ret);
break;
case SYM_MAX:
case SYM_MAXIMUM:
Find_Maximum_Of_Vector(vect, ret);
break;
default:
return FALSE;
}
Expand Down
69 changes: 69 additions & 0 deletions src/tests/units/vector-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,75 @@ Rebol [
===end-group===


===start-group=== "VECTOR ´minimum/maximum"
vi08: #(i8! [1 -2 0])
vi16: #(i16! [1 -2 0])
vi32: #(i32! [1 -2 0])
vi64: #(i64! [1 -2 0])
vu08: #(u8! [1 2 0])
vu16: #(u16! [1 2 0])
vu32: #(u32! [1 2 0])
vu64: #(u64! [1 2 0])
vf32: #(f32! [1 -2 0])
vf64: #(f64! [1 -2 0])
--test-- "Find minimum of the vector"
--assert vi08/min == -2
--assert vi16/min == -2
--assert vi32/min == -2
--assert vi64/min == -2
--assert vu08/min == 0
--assert vu16/min == 0
--assert vu32/min == 0
--assert vu64/min == 0
--assert vf32/min == -2.0
--assert vf64/min == -2.0
;; it can be used also full word
--assert vi08/minimum == -2
--test-- "Find maximum of the vector"
--assert vi08/max == 1
--assert vi16/max == 1
--assert vi32/max == 1
--assert vi64/max == 1
--assert vu08/max == 2
--assert vu16/max == 2
--assert vu32/max == 2
--assert vu64/max == 2
--assert vf32/max == 1.0
--assert vf64/max == 1.0
--assert vi08/maximum == 1
vi08: #(i8! [])
vi16: #(i16! [])
vi32: #(i32! [])
vi64: #(i64! [])
vu08: #(u8! [])
vu16: #(u16! [])
vu32: #(u32! [])
vu64: #(u64! [])
vf32: #(f32! [])
vf64: #(f64! [])
--test-- "Find minimum of the empty vector"
--assert none? vi08/min
--assert none? vi16/min
--assert none? vi32/min
--assert none? vi64/min
--assert none? vu08/min
--assert none? vu16/min
--assert none? vu32/min
--assert none? vu64/min
--assert none? vf32/min
--assert none? vf64/min
--test-- "Find maximum of the empty vector"
--assert none? vi08/max
--assert none? vi16/max
--assert none? vi32/max
--assert none? vi64/max
--assert none? vu08/max
--assert none? vu16/max
--assert none? vu32/max
--assert none? vu64/max
--assert none? vf32/max
--assert none? vf64/max

===start-group=== "VECTOR Compare"
--test-- "compare vectors"
;@@ https://github.com/Oldes/Rebol-issues/issues/458
Expand Down

0 comments on commit 2199450

Please sign in to comment.