function _quantAMMUnpack128Matrix(
int256[] memory _sourceArray,
uint _numberOfAssets
) internal pure returns (int256[][] memory targetArray) {
require(_sourceArray.length * 2 >= _numberOfAssets * _numberOfAssets, "Source cannot provide target");
targetArray = new int256[][]();
for (uint i; i < _numberOfAssets; ) {
targetArray[i] = new int256[]();
unchecked {
++i;
}
}
uint targetIndex;
uint targetRow;
for (uint i; i < _sourceArray.length; ) {
if (targetIndex < _numberOfAssets) {
targetArray[targetRow][targetIndex] = int256(int128(_sourceArray[i] >> 128));
unchecked {
++targetIndex;
}
if (targetIndex < _numberOfAssets) {
targetArray[targetRow][targetIndex] = int256(int128(_sourceArray[i]));
unchecked {
++targetIndex;
}
} else {
unchecked {
++targetRow;
targetIndex = 0;
}
if (targetRow < _numberOfAssets) {
targetArray[targetRow] = new int256[]();
if (targetIndex < _numberOfAssets) {
targetArray[targetRow][targetIndex] = int256(int128(_sourceArray[i]));
unchecked {
++targetIndex;
}
}
}
}
} else {
unchecked {
++targetRow;
targetIndex = 0;
}
if (targetRow < _numberOfAssets) {
targetArray[targetRow] = new int256[]();
targetArray[targetRow][targetIndex] = int256(int128(_sourceArray[i] >> 128));
unchecked {
++targetIndex;
}
if (targetIndex < _numberOfAssets) {
targetArray[targetRow][targetIndex] = int256(int128(_sourceArray[i]));
unchecked {
++targetIndex;
}
} else {
unchecked {
++targetRow;
targetIndex = 0;
}
if (targetRow < _numberOfAssets) {
targetArray[targetRow] = new int256[]();
}
}
}
}
unchecked {
++i;
}
}
if ((_numberOfAssets * _numberOfAssets) % 2 != 0) {
targetArray[_numberOfAssets - 1][_numberOfAssets - 1] = int256(
int128(_sourceArray[_sourceArray.length - 1])
);
}
}
new array of targetArray[][] is done at the quite beginning of function _quantAMMUnpack128Matrix(). Then during the process of unpack, if unpack to a new targetrow, new array again.