Sample solutions
Content |
Solution for Exercise 3.1
#include <stddef.h> #include <stdio.h> #include <stdlib.h> void initMatrix(size_t m, size_t n, double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t j=0; j<n; ++j) { for (size_t i=0; i<m; ++i) { A[i*incRowA+j*incColA] = i*n + j + 1; } } } void printMatrix(size_t m, size_t n, const double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t i=0; i<m; ++i) { for (size_t j=0; j<n; ++j) { printf("%8.3lf ", A[i*incRowA+j*incColA]); } printf("\n"); } printf("\n"); } // function dnrm1 double dnrm1(size_t n, const double *x, ptrdiff_t incX) { double alpha = 0; for (size_t i=0; i<n; ++i) { alpha += x[i*incX]; } return alpha; } // function dswap // TODO: implement dswap here // function daxpy // TODO: implement daxpy here int main() { size_t m = 7; size_t n = 8; ptrdiff_t incRowA = 1; ptrdiff_t incColA = m; double *A = malloc(m*n*sizeof(double)); initMatrix(m, n, A, incRowA, incColA); printf("A = \n"); printMatrix(m, n, A, incRowA, incColA); // Exercise 3.1: // ------------- printf("nrm1(A(1,:)) = %lf\n", dnrm1(n, &A[1*incRowA], incColA)); printf("nrm1(A(:,2)) = %lf\n", dnrm1(m, &A[2*incColA], incRowA)); size_t mn = (m<n) ? m : n; // length of diagonal printf("nrm1(diag(A)) = %lf\n", dnrm1(mn, A, incRowA+incColA)); // Exercise 3.2: // ------------- /* // TODO/FIXME: dswap(???); printf("After dswap(A(1,:), A(2,:))\n"); printMatrix(m, n, A, incRowA, incColA); // TODO/FIXME: dswap(???); printf("After dswap(A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); */ // Exercise 3.3: // ------------- /* // TODO/FIXME: daxpy(???); printf("After daxpy(3.0, A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); // TODO/FIXME: daxpy(???); printf("After daxpy(-2.5, A(1,:), A(3,:))\n"); printMatrix(m, n, A, incRowA, incColA); */ free(A); return 0; }
theon$ gcc -Wall -std=c99 -o blas1_example_sol1 blas1_example_sol1.c theon$ ./blas1_example_sol1 A = 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.000 11.000 12.000 13.000 14.000 15.000 16.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000 24.000 25.000 26.000 27.000 28.000 29.000 30.000 31.000 32.000 33.000 34.000 35.000 36.000 37.000 38.000 39.000 40.000 41.000 42.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 50.000 51.000 52.000 53.000 54.000 55.000 56.000 nrm1(A(1,:)) = 100.000000 nrm1(A(:,2)) = 189.000000 nrm1(diag(A)) = 196.000000 theon$
Solution for Exercise 3.2
#include <stddef.h> #include <stdio.h> #include <stdlib.h> void initMatrix(size_t m, size_t n, double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t j=0; j<n; ++j) { for (size_t i=0; i<m; ++i) { A[i*incRowA+j*incColA] = i*n + j + 1; } } } void printMatrix(size_t m, size_t n, const double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t i=0; i<m; ++i) { for (size_t j=0; j<n; ++j) { printf("%8.3lf ", A[i*incRowA+j*incColA]); } printf("\n"); } printf("\n"); } // function dnrm1 double dnrm1(size_t n, const double *x, ptrdiff_t incX) { double alpha = 0; for (size_t i=0; i<n; ++i) { alpha += x[i*incX]; } return alpha; } // function dswap void dswap(size_t n, double *x, ptrdiff_t incX, double *y, ptrdiff_t incY) { for (size_t i=0; i<n; ++i) { double t = x[i*incX]; x[i*incX] = y[i*incY]; y[i*incY] = t; } } // function daxpy // TODO: implement daxpy here int main() { size_t m = 7; size_t n = 8; ptrdiff_t incRowA = 1; ptrdiff_t incColA = m; double *A = malloc(m*n*sizeof(double)); initMatrix(m, n, A, incRowA, incColA); printf("A = \n"); printMatrix(m, n, A, incRowA, incColA); // Exercise 3.1: // ------------- printf("nrm1(A(1,:)) = %lf\n", dnrm1(n, &A[1*incRowA], incColA)); printf("nrm1(A(:,2)) = %lf\n", dnrm1(m, &A[2*incColA], incRowA)); size_t mn = (m<n) ? m : n; // length of diagonal printf("nrm1(diag(A)) = %lf\n", dnrm1(mn, A, incRowA+incColA)); // Exercise 3.2: // ------------- dswap(n, &A[1*incRowA], incColA, &A[2*incRowA], incColA); printf("After dswap(A(1,:), A(2,:))\n"); printMatrix(m, n, A, incRowA, incColA); dswap(m, &A[1*incColA], incRowA, &A[2*incColA], incRowA); printf("After dswap(A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); // Exercise 3.3: // ------------- /* // TODO/FIXME: daxpy(???); printf("After daxpy(3.0, A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); // TODO/FIXME: daxpy(???); printf("After daxpy(-2.5, A(1,:), A(3,:))\n"); printMatrix(m, n, A, incRowA, incColA); */ free(A); return 0; }
theon$ gcc -Wall -std=c99 -o blas1_example_sol2 blas1_example_sol2.c theon$ ./blas1_example_sol2 A = 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.000 11.000 12.000 13.000 14.000 15.000 16.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000 24.000 25.000 26.000 27.000 28.000 29.000 30.000 31.000 32.000 33.000 34.000 35.000 36.000 37.000 38.000 39.000 40.000 41.000 42.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 50.000 51.000 52.000 53.000 54.000 55.000 56.000 nrm1(A(1,:)) = 100.000000 nrm1(A(:,2)) = 189.000000 nrm1(diag(A)) = 196.000000 After dswap(A(1,:), A(2,:)) 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000 24.000 9.000 10.000 11.000 12.000 13.000 14.000 15.000 16.000 25.000 26.000 27.000 28.000 29.000 30.000 31.000 32.000 33.000 34.000 35.000 36.000 37.000 38.000 39.000 40.000 41.000 42.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 50.000 51.000 52.000 53.000 54.000 55.000 56.000 After dswap(A(:,1), A(:,2)) 1.000 3.000 2.000 4.000 5.000 6.000 7.000 8.000 17.000 19.000 18.000 20.000 21.000 22.000 23.000 24.000 9.000 11.000 10.000 12.000 13.000 14.000 15.000 16.000 25.000 27.000 26.000 28.000 29.000 30.000 31.000 32.000 33.000 35.000 34.000 36.000 37.000 38.000 39.000 40.000 41.000 43.000 42.000 44.000 45.000 46.000 47.000 48.000 49.000 51.000 50.000 52.000 53.000 54.000 55.000 56.000 theon$
Solution for Exercise 3.3
#include <stddef.h> #include <stdio.h> #include <stdlib.h> void initMatrix(size_t m, size_t n, double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t j=0; j<n; ++j) { for (size_t i=0; i<m; ++i) { A[i*incRowA+j*incColA] = i*n + j + 1; } } } void printMatrix(size_t m, size_t n, const double *A, ptrdiff_t incRowA, ptrdiff_t incColA) { for (size_t i=0; i<m; ++i) { for (size_t j=0; j<n; ++j) { printf("%8.3lf ", A[i*incRowA+j*incColA]); } printf("\n"); } printf("\n"); } // function dnrm1 double dnrm1(size_t n, const double *x, ptrdiff_t incX) { double alpha = 0; for (size_t i=0; i<n; ++i) { alpha += x[i*incX]; } return alpha; } // function dswap void dswap(size_t n, double *x, ptrdiff_t incX, double *y, ptrdiff_t incY) { for (size_t i=0; i<n; ++i) { double t = x[i*incX]; x[i*incX] = y[i*incY]; y[i*incY] = t; } } // function daxpy void daxpy(size_t n, double alpha, const double *x, ptrdiff_t incX, double *y, ptrdiff_t incY) { for (size_t i=0; i<n; ++i) { y[i*incY] += alpha*x[i*incX]; } } int main() { size_t m = 7; size_t n = 8; ptrdiff_t incRowA = 1; ptrdiff_t incColA = m; double *A = malloc(m*n*sizeof(double)); initMatrix(m, n, A, incRowA, incColA); printf("A = \n"); printMatrix(m, n, A, incRowA, incColA); // Exercise 3.1: // ------------- printf("nrm1(A(1,:)) = %lf\n", dnrm1(n, &A[1*incRowA], incColA)); printf("nrm1(A(:,2)) = %lf\n", dnrm1(m, &A[2*incColA], incRowA)); size_t mn = (m<n) ? m : n; // length of diagonal printf("nrm1(diag(A)) = %lf\n", dnrm1(mn, A, incRowA+incColA)); // Exercise 3.2: // ------------- dswap(n, &A[1*incRowA], incColA, &A[2*incRowA], incColA); printf("After dswap(A(1,:), A(2,:))\n"); printMatrix(m, n, A, incRowA, incColA); dswap(m, &A[1*incColA], incRowA, &A[2*incColA], incRowA); printf("After dswap(A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); // Exercise 3.3: // ------------- daxpy(m, 3.0, &A[1*incColA], incRowA, &A[2*incColA], incRowA); printf("After daxpy(3.0, A(:,1), A(:,2))\n"); printMatrix(m, n, A, incRowA, incColA); daxpy(n, -2.5, &A[1*incRowA], incColA, &A[3*incRowA], incColA); printf("After daxpy(-2.5, A(1,:), A(3,:))\n"); printMatrix(m, n, A, incRowA, incColA); free(A); return 0; }
theon$ gcc -Wall -std=c99 -o blas1_example_sol3 blas1_example_sol3.c theon$ ./blas1_example_sol3 A = 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 9.000 10.000 11.000 12.000 13.000 14.000 15.000 16.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000 24.000 25.000 26.000 27.000 28.000 29.000 30.000 31.000 32.000 33.000 34.000 35.000 36.000 37.000 38.000 39.000 40.000 41.000 42.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 50.000 51.000 52.000 53.000 54.000 55.000 56.000 nrm1(A(1,:)) = 100.000000 nrm1(A(:,2)) = 189.000000 nrm1(diag(A)) = 196.000000 After dswap(A(1,:), A(2,:)) 1.000 2.000 3.000 4.000 5.000 6.000 7.000 8.000 17.000 18.000 19.000 20.000 21.000 22.000 23.000 24.000 9.000 10.000 11.000 12.000 13.000 14.000 15.000 16.000 25.000 26.000 27.000 28.000 29.000 30.000 31.000 32.000 33.000 34.000 35.000 36.000 37.000 38.000 39.000 40.000 41.000 42.000 43.000 44.000 45.000 46.000 47.000 48.000 49.000 50.000 51.000 52.000 53.000 54.000 55.000 56.000 After dswap(A(:,1), A(:,2)) 1.000 3.000 2.000 4.000 5.000 6.000 7.000 8.000 17.000 19.000 18.000 20.000 21.000 22.000 23.000 24.000 9.000 11.000 10.000 12.000 13.000 14.000 15.000 16.000 25.000 27.000 26.000 28.000 29.000 30.000 31.000 32.000 33.000 35.000 34.000 36.000 37.000 38.000 39.000 40.000 41.000 43.000 42.000 44.000 45.000 46.000 47.000 48.000 49.000 51.000 50.000 52.000 53.000 54.000 55.000 56.000 After daxpy(3.0, A(:,1), A(:,2)) 1.000 3.000 11.000 4.000 5.000 6.000 7.000 8.000 17.000 19.000 75.000 20.000 21.000 22.000 23.000 24.000 9.000 11.000 43.000 12.000 13.000 14.000 15.000 16.000 25.000 27.000 107.000 28.000 29.000 30.000 31.000 32.000 33.000 35.000 139.000 36.000 37.000 38.000 39.000 40.000 41.000 43.000 171.000 44.000 45.000 46.000 47.000 48.000 49.000 51.000 203.000 52.000 53.000 54.000 55.000 56.000 After daxpy(-2.5, A(1,:), A(3,:)) 1.000 3.000 11.000 4.000 5.000 6.000 7.000 8.000 17.000 19.000 75.000 20.000 21.000 22.000 23.000 24.000 9.000 11.000 43.000 12.000 13.000 14.000 15.000 16.000 -17.500 -20.500 -80.500 -22.000 -23.500 -25.000 -26.500 -28.000 33.000 35.000 139.000 36.000 37.000 38.000 39.000 40.000 41.000 43.000 171.000 44.000 45.000 46.000 47.000 48.000 49.000 51.000 203.000 52.000 53.000 54.000 55.000 56.000 theon$