1 // This code has been mechanically translated from the original FORTRAN 2 // code at http://netlib.org/minpack. 3 4 /** Authors: Lars Tandle Kyllingstad 5 Copyright: Copyright (c) 2009, Lars T. Kyllingstad. All rights reserved. 6 License: Boost Licence 1.0 7 */ 8 module scid.ports.minpack.qform; 9 10 11 private import std.algorithm: min; 12 13 14 15 16 /** This subroutine proceeds from the computed QR factorization of 17 an m by n matrix a to accumulate the m by m orthogonal matrix 18 Q from its factored form. 19 20 Params: 21 m = a positive integer input variable set to the number 22 of rows of a and the order of q. 23 n = a positive integer input variable set to the number 24 of columns of a. 25 q = an array of length m^2. On input the full lower trapezoid in 26 the first min(m,n) columns of Q contains the factored form. 27 on output Q has been accumulated into a square matrix. 28 ldq = a positive integer input variable not less than m 29 which specifies the leading dimension of the array q. 30 wa = a work array of length m. 31 */ 32 void qform(Real)(size_t m, size_t n, Real* q, size_t ldq, Real* wa) 33 { 34 size_t i, j, k, l; 35 36 enum : Real 37 { 38 one = 1.0, 39 zero = 0.0 40 } 41 42 43 // Zero out upper triangle of Q in the first min(m,n) columns. 44 size_t minmn = min(m, n); 45 if (minmn >= 2) 46 { 47 for (j=1; j<minmn; j++) 48 { 49 for (i=0; i<j; i++) 50 q[i+j*ldq] = zero; 51 } 52 } 53 54 55 // Initialize remaining columns to those of the identity matrix. 56 if (m > n) 57 { 58 for (j=n; j<m; j++) 59 { 60 for (i=0; i<m; i++) 61 q[i+j*ldq] = zero; 62 q[j+j*ldq] = one; 63 } 64 } 65 66 67 // Accumulate Q from its factored form. 68 Real sum, temp; 69 for (l=0; l<minmn; l++) 70 { 71 k = minmn - l - 1; 72 for (i=k; i<m; i++) 73 { 74 wa[i] = q[i+k*ldq]; 75 q[i+k*ldq] = zero; 76 } 77 q[k+k*ldq] = one; 78 79 if (wa[k] != zero) 80 { 81 for (j=k; j<m; j++) 82 { 83 sum = zero; 84 for (i=k; i<m; i++) 85 sum += q[i+j*ldq]*wa[i]; 86 temp = sum/wa[k]; 87 for (i=k; i<m; i++) 88 q[i+j*ldq] = q[i+j*ldq] - temp*wa[i]; 89 } 90 } 91 } 92 } 93 94 95 unittest { alias qform!(real) rqform; }