void hitMatrix_initialize(int4 queryLength, int4 maximumSubjectLength, unsigned char* startAddress)
{
	int4 numDiagonals;
	unsigned char **minOffset, **offset, **maxOffset;

    // Use more memory efficient but slower hit matrix for nucleotide
    if (encoding_alphabetType == encoding_nucleotide)
    {
        // Calculate number of diagonals that will be required during search
        numDiagonals = 1;
        while (numDiagonals < queryLength + parameters_wordSize)
        {
            numDiagonals <<= 1;
        }

        // Construct mask
        hitMatrix_diagonalMask = numDiagonals - 1;

        // Declare memory for diagonal slots
        hitMatrix_furthest = (unsigned char**)global_malloc(sizeof(unsigned char*) * numDiagonals);
        minOffset = hitMatrix_furthest;
	}
    // Use less memory efficient but faster hit matrix for protein
    else
    {
        // Maximum number of diagonals that will be required during search
        numDiagonals = queryLength + maximumSubjectLength - parameters_wordSize + 1;
        minOffset = (unsigned char**)global_malloc(sizeof(unsigned char*) * numDiagonals);

        // Advance array pointer to allow offset values ranging from
        // -queryLength to subjectLength - wordSize
        hitMatrix_furthest = minOffset + queryLength;
    }

	// Record query length
	hitMatrix_queryLength = queryLength;

	// Start from smallest possible offset value and iterate through to largest
	offset = minOffset;
	maxOffset = minOffset + numDiagonals;

	// For each diagonal, reset furthest to address at start of file
	while (offset < maxOffset)
	{
		*offset = startAddress;
		offset++;
	}
}

// Reinitialize the hit matrix so all values point to start of new file
void hitMatrix_reinitialize(int4 queryLength, int4 maximumSubjectLength, unsigned char* startAddress)
{
	int4 numDiagonals;
	unsigned char **minOffset, **offset, **maxOffset;

    if (encoding_alphabetType == encoding_nucleotide)
    {
        // Calculate number of diagonals that will be required during search
        numDiagonals = 1;
        while (numDiagonals < queryLength + parameters_wordSize)
        {
            numDiagonals <<= 1;
        }

        minOffset = hitMatrix_furthest;
	}
    // Use less memory efficient but faster hit matrix for protein
    else
    {
        // Maximum number of diagonals that will be required during search
        numDiagonals = queryLength + maximumSubjectLength - parameters_wordSize + 1;

        minOffset = hitMatrix_furthest - queryLength;
    }

	// Start from smallest possible offset value and iterate through to largest
	offset = minOffset;
	maxOffset = minOffset + numDiagonals;

	// For each diagonal, reset furthest to address at start of file
	while (offset < maxOffset)
	{
		*offset = startAddress;
		offset++;
	}
}

// Free the matrix
void hitMatrix_free()
{
    if (encoding_alphabetType == encoding_protein)
		hitMatrix_furthest -= hitMatrix_queryLength;
	free(hitMatrix_furthest);
}
