/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The arrays provided in Pinescript are linear 1D strucures that can be seen either as a large vertical stack or
// a horizontal row containing a list of values, colors, bools,..
//
// With the FUNCTIONS in this script the 1D ARRAY LIST can be CONVERTED INTO A 2D MATRIX form
//
//
///////////////////////////////////////////
/// BASIC INFO ON THE MATRIX STRUCTURE: ///
///////////////////////////////////////////
//
// The matrix is set up as an 2D structure and is devided in ROWS and COLUMNS.
// following the standard mathematical notation:
//
// a 3 x 4 matrix = 4 columns
// 0 1 2 3 column index
// 0 [a b c d]
// 3 rows 1 [e f g h]
// 2 [i j k l]
// row
// index
//
// With the use of some purpose-built functions, values can be placed or retrieved in a specific column of a certain row
// this can be done by intuitively using row_nr and column_nr coördinates,
// without having to worry on what exact index of the Pine array this value is located (the functions do these conversions for you)
//
//
// the syntax I propose for the 2D Matrix array has the following structure:
//
// - the array starts with 2 VALUES describing the DIMENSION INFORMATION, (rows, columns)
// these are ignored in the actual calculations and serve as a metadata header (similar to the "location, time,... etc." data that is stored in photo files)
// so the array always carries it's own info about the nr. of rows and columns and doesn't need is seperate "info" file!
//
// To stay consistent with the standard Pinescript (array and [lookback]) indexing:
// - indexes for sheets and columns start from 0 (first) and run up to the (total nr of sheets or columns) - 1
// - indexes for rows also start from 0 (most recent, cfr.[lookback]) and run up to the (total nr of rows) - 1
//
// - this 2 value metadata header is followed by the actual df data
// the actual data array can consist of (100,000 - 2) usable items,
//
// In a theoretical example, you can have a matrix with almost 20,000 rows with each 5 columns of data (eg. open, high, low, close, volume) in it!!!
//
//
///////////////////////////////////
/// SCHEMATIC OF THE STRUCTURE: ///
///////////////////////////////////
//
////// (metadata header with dimensions info)
//
// (0) (1) (array index)
// [nr_of_rows/records, nr_of_columns,
//
//
////// (actual matrix array data)
//
// 0 1 2 3 column_index
//
// (2) (3) (4) (5) (array index)
// 0 record0_val0, record0_val1, record0_val2, record0_val3, ...,
//
// (6) (7) (8) (9) (array index)
// 1 record1_val0, record1_val1, record1_val2, record1_val3, ...,
//
// (10) (11) (12) (13) (array index)
// 2 record2_val0, record2_val1, record2_val2, record2_val3, ...,
//
// 3 ...
//
// row_index
//
////////////////////////////////////
/// DATA MANIPULATION FUNCTIONS: ///
////////////////////////////////////
//
// A set of functions are implemented to write info to and retrieve info from the dataframe.
// Of course the possibilities are not limited to the functions here, these were written because they were needed for the script!
// A whole list of other functions can be easily written for other manipulation purposes.
// The ones written in the script are 2D versions of most of the functions that are provided for normal 1D arrays.
//
//
///////////////////////////////////////////////////////////////////////
/// LIST OF FUNCTIONS contained in this script: ///
/// (many other can of course be written, using the same structure) ///
///////////////////////////////////////////////////////////////////////
//
// - INFO functions
// * get the number of COLUMNS
// * get the number of ROWS
// * get the total SIZE (number of columns, number of rows)
//
// - INITIALISATION and SET functions (commands to build the 2D matrix)
// * MATRIX INITIALISATION function, builds 2D matrix with dimensional metadata/size in first 2 values //
// a new matrix array is built (cfr. the conventions I propose above) containing a certain nr of rows and columns
// * function to SET a single value in a certain row/lookback period and column
//
// - GET functions (to retrieve info from the 2D matrix)
// * function to GET/retrieve a single VALUE from a certain row/lookback period and column
// * function to cut of the metadata header and return the array body (as an array)
// * function to GET/retrieve the values from a ROW/RECORD from a certain row/lookback period, the values are returned as an array
//
// - 1D - 2D COORDINATE CONVERSION FUNCTIONS (handy with for loop indexes) ///
// * function to get the ROW INDEX in a 2D matrix from the 1D array index
// * function to get the COLUMN INDEX in a 2D matrix from the 1D array index
// * function to get (row, column) coordinates in a 2D matrix from the 1D array index
// * function to get the 1D array index from (row, column) coordinates in a 2D matrix
//
// - Matrix MANIPULATION functions
// * function to ADD a ROW/RECORD on the TOP of the array, shift the whole list one down and REMOVE the OLDEST row/record
// (2D version of "unshift" + "pop" but with a whole row at once)
// * function to REMOVE one or more ROWS/RECORDS from a 2D matrix
// (if from_row == to_row, only this row is removed)
// * function to REMOVE one or more COLUMNS from a 2D matrix
// (if from_column == to_column, only this column is removed)
// * function to INSERT an ARRAY of ROWS/RECORDS at a certain row number in a 2D matrix
// * function to INSERT an ARRAY of COLUMNS at a certain column number in a 2D matrix
// * function to APPEND/ADD an ARRAY of ROWS/RECORDS to the BOTTOM of a 2D matrix
// * function to APPEND/ADD an ARRAY of COLUMNS to the SIDE of a 2D matrix
// * function to POP/REMOVE and return the last ROW/RECORD from the BOTTOM of a 2D matrix
// * function to POP/REMOVE and return the last column from the SIDE of a 2D matrix
//
// - function to print a matrix
// This function is mainly used for debugging purposes and displays the array as a 2D matrix notation
//
//
// Enjoy!
// JD.
//
// #NotTradingAdvice #DYOR
//
// Disclaimer.
// I AM NOT A FINANCIAL ADVISOR.
// THESE IDEAS ARE NOT ADVICE AND ARE FOR EDUCATION PURPOSES ONLY.
// ALWAYS DO YOUR OWN RESEARCH!