Another approach is you can represent each row as a string, i.e. mapping the 2D array into an 1D array. Then, all you need to do is unpack and repack the row's string whenever you make an edit:
# Init a 4x5 matrix
a=("00 01 02 03 04" "10 11 12 13 14" "20 21 22 23 24" "30 31 32 33 34")
aset() {
row=$1
col=$2
value=$3
IFS=' ' read -r -a tmp <<< "${a[$row]}"
tmp[$col]=$value
a[$row]="${tmp[@]}"
}
# Set a[2][3] = 9999
aset 2 3 9999
# Show result
for r in "${a[@]}"; do
echo $r
done
Outputs:
00 01 02 03 04
10 11 12 13 14
20 21 22 9999 24
30 31 32 33 34