diff --git a/core/formula/doc/index.rst b/core/formula/doc/index.rst
index f4ffd3f03d..811412cf51 100644
--- a/core/formula/doc/index.rst
+++ b/core/formula/doc/index.rst
@@ -148,6 +148,9 @@ and toIndex. The indexes must be valid, e.g. fromIndex > 0, fromIndex < toIndex
**arrayRangeOf(VNumberArray array)** - Returns a Display Range of the given array
This includes the display min, max
+**arrayReversal(VNumberArray array)** - Returns a VNumberArray with the elements in reverse order
+(the first element becomes the last, the last becomes the first).
+
**arrayStats(VNumberArray array)** - Returns a VStatistic with the statistical information of the given array
This includes the average, min, max, and element count
@@ -163,8 +166,6 @@ The down-sampling is performed using the Largest-Triangle-Three-Buckets (LTTB) a
**arrayCumSum(VNumberArray array)** - Returns a VNumberArray where each element is defined as the cumulative sum of the input array.
-String
-------
**concat(String s...)** - Concatenate a list of strings of a string array.
**strEqual(String s1, String s2)** - Compare value of 2 strings. Return true if s1 equals s2, else false.
diff --git a/core/formula/src/main/java/org/csstudio/apputil/formula/array/ArrayReversalFunction.java b/core/formula/src/main/java/org/csstudio/apputil/formula/array/ArrayReversalFunction.java
new file mode 100644
index 0000000000..4fb0dc7d15
--- /dev/null
+++ b/core/formula/src/main/java/org/csstudio/apputil/formula/array/ArrayReversalFunction.java
@@ -0,0 +1,98 @@
+package org.csstudio.apputil.formula.array;
+
+import org.csstudio.apputil.formula.Formula;
+import org.epics.util.array.ListDouble;
+import org.epics.util.array.ListNumber;
+import org.epics.vtype.Alarm;
+import org.epics.vtype.Display;
+import org.epics.vtype.VNumberArray;
+import org.epics.vtype.VType;
+import org.phoebus.core.vtypes.VTypeHelper;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+
+/**
+ * A formula function for reversing the given array.
+ *
+ * The function allows for reversing the order of elements in an array, such that the first element
+ * becomes the last, the second element becomes the second to last, and so on.
+ *
+ *
+ * Arguments:
+ *
+ * - array: The input numeric array to reverse.
+ *
+ *
+ * Example:
+ *
+ * If given an array [1, 2, 3, 4, 5], the result will be [5, 4, 3, 2, 1].
+ *
+ *
+ * @author Kunal Shroff
+ */
+public class ArrayReversalFunction extends BaseArrayFunction {
+
+ @Override
+ public String getName() {
+ return "arrayReverse";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Reverses the given numeric array so that the first element becomes the last and vice versa.";
+ }
+
+ @Override
+ public List getArguments() {
+ return List.of("array");
+ }
+
+ /**
+ * Reverses the elements of a numeric array.
+ *
+ * @param array The input numeric array (VNumberArray) to reverse.
+ * @return A {@link VNumberArray} containing the reversed elements.
+ */
+ protected VType getArrayData(final VNumberArray array) {
+ return VNumberArray.of(reverse(array.getData()), Alarm.none(), array.getTime(), Display.none());
+ }
+
+ private static ListDouble reverse(final ListNumber data) {
+ return new ListDouble() {
+ @Override
+ public double getDouble(int index) {
+ return data.getDouble(data.size() - 1 - index);
+ }
+
+ @Override
+ public int size() {
+ return data.size();
+ }
+ };
+ }
+
+ /**
+ * Computes the function's result by reversing the provided array.
+ *
+ * @param args The arguments to the function:
+ * - args[0]: The input array to reverse.
+ * @return A {@link VType} containing the reversed array.
+ * @throws Exception If an invalid number of arguments or incorrect argument types are provided.
+ */
+ @Override
+ public VType compute(final VType... args) throws Exception {
+ if (args.length != 1) {
+ throw new Exception("Function " + getName() +
+ " requires 1 argument but received " + Arrays.toString(args));
+ }
+ if (!VTypeHelper.isNumericArray(args[0])) {
+ Formula.logger.log(Level.WARNING, "Function " + getName() +
+ " takes array but received " + Arrays.toString(args));
+ return DEFAULT_NAN_DOUBLE_ARRAY;
+ } else {
+ return getArrayData((VNumberArray) args[0]);
+ }
+ }
+}
diff --git a/core/formula/src/main/resources/META-INF/services/org.csstudio.apputil.formula.spi.FormulaFunction b/core/formula/src/main/resources/META-INF/services/org.csstudio.apputil.formula.spi.FormulaFunction
index 8380212c2e..1da8cbd7a3 100644
--- a/core/formula/src/main/resources/META-INF/services/org.csstudio.apputil.formula.spi.FormulaFunction
+++ b/core/formula/src/main/resources/META-INF/services/org.csstudio.apputil.formula.spi.FormulaFunction
@@ -59,6 +59,7 @@ org.csstudio.apputil.formula.array.ArrayScalarDivisionFunction
org.csstudio.apputil.formula.array.ArrayInverseScalarDivisionFunction
org.csstudio.apputil.formula.array.ArrayOfFunction
org.csstudio.apputil.formula.array.ArrayRangeOfFunction
+org.csstudio.apputil.formula.array.ArrayReversalFunction
org.csstudio.apputil.formula.array.ArraySampleWithLTTBFunction
org.csstudio.apputil.formula.array.ArraySampleWithStrideFunction
org.csstudio.apputil.formula.array.ArrayStatsFunction
diff --git a/core/formula/src/test/java/org/csstudio/apputil/formula/array/ArrayReversalFunctionTest.java b/core/formula/src/test/java/org/csstudio/apputil/formula/array/ArrayReversalFunctionTest.java
new file mode 100644
index 0000000000..6ca04aa43f
--- /dev/null
+++ b/core/formula/src/test/java/org/csstudio/apputil/formula/array/ArrayReversalFunctionTest.java
@@ -0,0 +1,54 @@
+package org.csstudio.apputil.formula.array;
+
+import org.epics.util.array.ArrayDouble;
+import org.epics.util.array.ListDouble;
+import org.epics.vtype.Alarm;
+import org.epics.vtype.Display;
+import org.epics.vtype.Time;
+import org.epics.vtype.VNumberArray;
+import org.epics.vtype.VType;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ArrayReversalFunctionTest {
+ private final ArrayReversalFunction function = new ArrayReversalFunction();
+
+ @Test
+ void testReverseTypicalArray() throws Exception {
+ VNumberArray input = VNumberArray.of(ArrayDouble.of(1, 2, 3, 4, 5), Alarm.none(), Time.now(), Display.none());
+ VType result = function.compute(input);
+ assertTrue(result instanceof VNumberArray);
+ double[] reversed = ((VNumberArray) result).getData().toArray(new double[input.getData().size()]);
+ assertArrayEquals(new double[]{5, 4, 3, 2, 1}, reversed, 1e-9);
+ }
+
+ @Test
+ void testReverseEmptyArray() throws Exception {
+ VNumberArray input = VNumberArray.of(ArrayDouble.of(), Alarm.none(), Time.now(), Display.none());
+ VType result = function.compute(input);
+ assertTrue(result instanceof VNumberArray);
+ double[] reversed = ((VNumberArray) result).getData().toArray(new double[input.getData().size()]);
+ assertArrayEquals(new double[]{}, reversed, 1e-9);
+ }
+
+ @Test
+ void testReverseSingleElementArray() throws Exception {
+ VNumberArray input = VNumberArray.of(ArrayDouble.of(42), Alarm.none(), Time.now(), Display.none());
+ VType result = function.compute(input);
+ assertTrue(result instanceof VNumberArray);
+ double[] reversed = ((VNumberArray) result).getData().toArray(new double[input.getData().size()]);
+ assertArrayEquals(new double[]{42}, reversed, 1e-9);
+ }
+
+ @Test
+ void testReverseNegativeNumbers() throws Exception {
+ VNumberArray input = VNumberArray.of(ArrayDouble.of(-1, -2, -3), Alarm.none(), Time.now(), Display.none());
+ VType result = function.compute(input);
+ assertTrue(result instanceof VNumberArray);
+ double[] reversed = ((VNumberArray) result).getData().toArray(new double[input.getData().size()]);
+ assertArrayEquals(new double[]{-3, -2, -1}, reversed, 1e-9);
+ }
+}