Вот пример одного из возможных решений, с которого можно начать. Возможны другие методы. Этот код не проверен.
#include <stdlib.h>
typedef float T;
// Attempt to allocate space for a bidiagonal matrix of size n-by-n.
T *MallocBidiagonalMatrix(size_t n) { return malloc((2*n-1) * sizeof(T)); }
// Free a bidiagonal matrix.
void FreeBidiagonalMatrix(T *p) { free(p); }
// Return a reference to element [r, c] of bidiagonal matrix p of size n-by-n.
T *BidiagonalMatrixElement(size_t n, T *p, size_t r, size_t c)
{
static T Zero = 0;
// The diagonal elements are stored from p[0] to p[n-1].
if (r == c)
return p+r;
// The existing off-diagonal elements are stored from p[n] to p[2*n-2].
if (r == c-1)
return p+n+r;
/* For non-existing (zero) elements, return a reference to zero. (Callers
are expected not to write to this address. If they do, the behavior is
not defined.)
*/
else
return &Zero;
}
/* Show how a bidiagonal matrix previously allocated with
MallocBidiagonalMatrix might be initialized.
*/
void InitializeBidiagonalMatrix(size_t n, T *p)
{
// Initialize the diagonal elements.
for (size_t i = 0; i < n; ++i)
*BidiagonalMatrixElement(n, p, i, i) = rand();
// Initialize the off-diagonal elements.
for (size_t i = 0; i < n-1; ++i)
*BidiagonalMatrixElement(n, p, i, i+1) = rand();
}
/* Show how a bidiagonal matrix might be used in arithmetic by demonstrating
a simple matrix addition. The n-by-n bidiagonal matrix p is added to
n-by-n matrix q.
*/
void AddBidiagonalMatrixToDenseMatrix(size_t n, T *p, T (*q)[n])
{
for (size_t r = 0; r < n; ++r)
for (size_t c = 0; c < n; ++c)
q[r][c] += *BidiagonalMatrixElement(n, p, r, c);
}
Обратите внимание, что AddBidiagonalMatrixToDenseMatrix
можно оптимизировать для обработки только сохраненных элементов. Однако данная реализация демонстрирует, как может работать алгоритм, не обращающий внимания на то, какие элементы фактически хранятся.