NdArrayDemo.java

package org.sadisamir.ndarray.demo;

import org.sadisamir.ndarray.NdArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Demonstrates NDArray library features.
 * This class serves as the entrypoint for the Docker demo container.
 */
public class NdArrayDemo {

    private static final Logger LOGGER = LoggerFactory.getLogger(NdArrayDemo.class);
    private static final String SEPARATOR = "─".repeat(50);
    private static final String RESULT_FORMAT = "  Result: {}";
    private static final String RESULT_LABEL = "  Result:";
    private static final String SHAPE_FORMAT = "  shape:  {}";

    public static void main(String[] args) {
        printBanner();
        demo1DArrayCreation();
        demo2DArrayCreation();
        demoArithmeticOperations();
        demoOptionalFeatures();
        demoReshape();
        demoLargeArrayDisplay();
        printFooter();
    }

    private static void printBanner() {
        LOGGER.info("");
        LOGGER.info("╔══════════════════════════════════════════════════╗");
        LOGGER.info("║         NDArray Library Feature Showcase         ║");
        LOGGER.info("║       NumPy-inspired arrays for Java             ║");
        LOGGER.info("╚══════════════════════════════════════════════════╝");
        LOGGER.info("");
    }

    private static void demo1DArrayCreation() {
        printSection("1D Array Creation");

        LOGGER.info("Creating array from values: NdArray.array(new float[]{{1, 2, 3, 4, 5}})");
        NdArray arr = NdArray.array(new float[]{1f, 2f, 3f, 4f, 5f});
        LOGGER.info(RESULT_FORMAT, arr);
        LOGGER.info("  ndim:   {}", arr.getNdim());
        logShape(arr.getShape());
        LOGGER.info("  size:   {}", arr.getSize());
        LOGGER.info("");

        LOGGER.info("Creating zeros array: NdArray.zeros(4)");
        NdArray zeros = NdArray.zeros(4);
        LOGGER.info(RESULT_FORMAT, zeros);
        LOGGER.info("");

        LOGGER.info("Creating range array: NdArray.arange(0, 10, 2)");
        NdArray range = NdArray.arange(0f, 10f, 2f);
        LOGGER.info(RESULT_FORMAT, range);
        LOGGER.info("");
    }

    private static void demo2DArrayCreation() {
        printSection("2D Array (Matrix) Creation");

        LOGGER.info("Creating 2D array from matrix:");
        LOGGER.info("  NdArray.array(new float[][]{{{{1, 2, 3}}, {{4, 5, 6}}}})");
        NdArray matrix = NdArray.array(new float[][]{{1f, 2f, 3f}, {4f, 5f, 6f}});
        LOGGER.info(RESULT_LABEL);
        printMatrix(matrix);
        LOGGER.info("  ndim:   {}", matrix.getNdim());
        logShape(matrix.getShape());
        LOGGER.info("  size:   {}", matrix.getSize());
        LOGGER.info("");
    }

    private static void demoArithmeticOperations() {
        printSection("Arithmetic Operations");

        NdArray a = NdArray.array(new float[]{1f, 2f, 3f});
        NdArray b = NdArray.array(new float[]{10f, 20f, 30f});

        LOGGER.info("Array a: {}", a);
        LOGGER.info("Array b: {}", b);
        LOGGER.info("");

        LOGGER.info("Element-wise addition: a.add(b)");
        NdArray sum = a.add(b);
        LOGGER.info(RESULT_FORMAT, sum);
        LOGGER.info("");

        LOGGER.info("In-place addition: a.addInPlace(b)");
        NdArray c = NdArray.array(new float[]{1f, 2f, 3f});
        LOGGER.info("  Before: {}", c);
        c.addInPlace(b);
        LOGGER.info("  After:  {}", c);
        LOGGER.info("");

        LOGGER.info("2D Matrix addition:");
        NdArray m1 = NdArray.array(new float[][]{{1f, 2f}, {3f, 4f}});
        NdArray m2 = NdArray.array(new float[][]{{10f, 10f}, {10f, 10f}});
        LOGGER.info("  Matrix 1:");
        printMatrix(m1);
        LOGGER.info("  Matrix 2:");
        printMatrix(m2);
        LOGGER.info("  Sum (m1.add(m2)):");
        printMatrix(m1.add(m2));
        LOGGER.info("");
    }

    private static void demoOptionalFeatures() {
        printSection("Optional Features");

        NdArray base = NdArray.array(new float[]{1f, 2f, 3f});
        LOGGER.info("Scalar addition: base.add(10f)");
        LOGGER.info("  Base:    {}", base);
        NdArray shifted = base.add(10f);
        LOGGER.info("  Shifted: {}", shifted);
        LOGGER.info("");

        LOGGER.info("Reduction: shifted.sum()");
        LOGGER.info("  Total:   {}", shifted.sum());
        LOGGER.info("");
    }

    private static void demoReshape() {
        printSection("Reshape Operations");

        LOGGER.info("Creating 1D array: NdArray.arange(6)");
        NdArray flat = NdArray.arange(6f);
        LOGGER.info(RESULT_FORMAT, flat);
        logShape(flat.getShape());
        LOGGER.info("");

        LOGGER.info("Reshaping to 2x3: flat.reshape(2, 3)");
        NdArray reshaped = flat.reshape(2, 3);
        LOGGER.info(RESULT_LABEL);
        printMatrix(reshaped);
        logShape(reshaped.getShape());
        LOGGER.info("");

        LOGGER.info("Reshaping to 3x2: flat.reshape(3, 2)");
        NdArray reshaped2 = flat.reshape(3, 2);
        LOGGER.info(RESULT_LABEL);
        printMatrix(reshaped2);
        logShape(reshaped2.getShape());
        LOGGER.info("");
    }

    private static void demoLargeArrayDisplay() {
        printSection("Large Array Display (Ellipsis)");

        LOGGER.info("Creating large array: NdArray.arange(20)");
        NdArray large = NdArray.arange(20f);
        LOGGER.info(RESULT_FORMAT, large);
        LOGGER.info("  (Note: Large arrays use ellipsis notation)");
        LOGGER.info("");
    }

    private static void printSection(String title) {
        LOGGER.info(SEPARATOR);
        LOGGER.info("▶ {}", title);
        LOGGER.info(SEPARATOR);
        LOGGER.info("");
    }

    private static void printMatrix(NdArray matrix) {
        if (LOGGER.isInfoEnabled()) {
            String[] lines = matrix.toString().split("\n");
            for (String line : lines) {
                LOGGER.info("    {}", line);
            }
        }
    }

    private static void logShape(int[] shape) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info(SHAPE_FORMAT, formatShape(shape));
        }
    }

    private static String formatShape(int[] shape) {
        StringBuilder sb = new StringBuilder("(");
        for (int i = 0; i < shape.length; i++) {
            if (i > 0) sb.append(", ");
            sb.append(shape[i]);
        }
        sb.append(")");
        return sb.toString();
    }

    private static void printFooter() {
        LOGGER.info(SEPARATOR);
        LOGGER.info("✓ Demo completed successfully!");
        LOGGER.info("  Repository: https://github.com/sMouaad/DevOps-Project");
        LOGGER.info(SEPARATOR);
        LOGGER.info("");
    }
}