Här kommer jag att ha olika matriser på a, q och r. Men dessa matriser allokeras bara EN gång.
Kod: Markera allt
void cut_internal_qr(matrix* a, int start_n, int stop_n, int start_m, int stop_m, float* b, int out_columns);
float dot_internal_qr(float* a, float* b, int n);
float norm_internal_qr(float* a, int n);
/*===========================================================================
 * qr
 * Get Q and R matrix from matrix by using Modified Gram-Schmidt method
 * Input: Matrix
 * Return: void
 * Works: OK
 *=========================================================================*/
void qr(matrix* a, matrix* q, matrix* r) {
	// Get info about matrix a
	int n = a->row;
	int m = a->column;
	float* ptr = a->data;
	// Get data
	float* ptr_q = q->data;
	float* ptr_r = r->data;
	float c1[n];
	float c2[n];
	memset(c1, 0, sizeof(c1));
	memset(c2, 0, sizeof(c2));
	for(int k = 0; k < m; k++){
		// Insert vector
		for(int j = 0; j < n; j++)
			*((ptr_q + j*n) + k) = *((ptr + j*n) + k);
		// Do the dot product
		for(int i = 0; i < k; i++){
			cut_internal_qr(q, 0, n-1, i, i, c1, 1);
			cut_internal_qr(q, 0, n-1, k, k, c2, 1);
			*((ptr_r + i*m)+k) = dot_internal_qr(c1, c2, n);
			// Insert vector again
			for(int j = 0; j < n; j++)
				*((ptr_q + j*n) + k) = *((ptr_q + j*n) + k) - *((ptr_r + i*m)+k)*(*((ptr_q + j*n) +i));
		}
		cut_internal_qr(q, 0, n-1, k, k, c1, 1);
		*((ptr_r+k*m)+k) = -norm_internal_qr(c1, n); // Important with negative
		// Insert vector again
		for(int j = 0; j < n; j++){
			if(*((ptr_r + k*m) + k) ==  0){
				*((ptr_r + k*m) + k) = pow(2.2204, -16); // Same as eps command in MATLAB
			}
			*((ptr_q + j*n) + k) = (*((ptr_q + j*n) + k)) / (*((ptr_r + k*m) + k));
		}
	}
}
void cut_internal_qr(matrix* a, int start_n, int stop_n, int start_m, int stop_m, float* b, int out_columns) {
	int in_columns = a->column;
	float* data = a->data + start_n * in_columns + start_m;
	// Instead of having two for loops, we just copy the whole row at once.
	for (int i = start_n; i < stop_n + 1; i++) {
		memcpy(b, data, sizeof(float) * out_columns);
		b += out_columns;
		data += in_columns;
	}
}
float dot_internal_qr(float* a, float* b, int n) {
	// Reset
	float sum = 0;
	// Multiply each row
	for (int i = 0; i < n; ++i) {
		sum += (*(a + i)) * (*(b + i));
	}
	return sum;
}
float norm_internal_qr(float* a, int n) {
	float sum = 0; // Initial
	for (int i = 0; i < n; i++)
		sum += (*(a + i)) * (*(a + i));
	return sqrt(sum);
}
/* MATLAB CODE
 * function [Q,R] =  mgs(X)
    % Modified Gram-Schmidt.  [Q,R] = mgs(X);
    % G. W. Stewart, "Matrix Algorithms, Volume 1", SIAM, 1998.
    [n,p] = size(X);
    Q = zeros(n,p);
    R = zeros(p,p);
    for k = 1:p
        Q(:,k) = X(:,k);
        for i = 1:k-1
            R(i,k) = Q(:,i)'*Q(:,k);
            Q(:,i)'*Q(:,k)
            Q(:,k) = Q(:,k) - R(i,k)*Q(:,i);
        end
        R(k,k) = -norm(Q(:,k))';
        Q(:,k) = Q(:,k)/R(k,k);
    end
end
 */