From 4d2d4f5d7a9f584061b85ef707b3cccee814cbc6 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Wed, 15 Nov 2023 14:43:22 -0700 Subject: [PATCH] add hw 7 and documentation for q1 and part of q2 in lizfcm api reference --- doc/software_manual.org | 68 +++++++++++++++++++++++++++++++++++++++-- homeworks/hw-7.org | 10 ++++++ src/eigen.c | 6 ++-- 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 homeworks/hw-7.org diff --git a/doc/software_manual.org b/doc/software_manual.org index 2a3b347..a54006a 100644 --- a/doc/software_manual.org +++ b/doc/software_manual.org @@ -1,4 +1,4 @@ -#+TITLE: LIZFCM Software Manual (v0.3) +#+TITLE: LIZFCM Software Manual (v0.4) #+AUTHOR: Elizabeth Hunt #+LATEX_HEADER: \notindent \notag \usepackage{amsmath} \usepackage[a4paper,margin=1in,portrait]{geometry} #+LATEX: \setlength\parindent{0pt} @@ -286,7 +286,6 @@ double sum_v(Array_double *v) { } #+END_SRC - *** ~scale_v~ + Author: Elizabeth Hunt + Name: ~scale_v~ @@ -993,6 +992,71 @@ Line *least_squares_lin_reg(Array_double *x, Array_double *y) { return line; } #+END_SRC + +** Eigen-Adjacent +*** ~dominant_eigenvalue~ ++ Author: Elizabeth Hunt ++ Name: ~dominant_eigenvalue~ ++ Location: ~src/eigen.c~ ++ Input: a pointer to an invertible matrix ~m~, an initial eigenvector guess ~v~ (that is non + zero or orthogonal to an eigenvector with the dominant eigenvalue), a ~tolerance~ and + ~max_iterations~ that act as stop conditions ++ Output: the dominant eigenvalue with the highest magnitude, approximated with the Power + Iteration Method + +#+BEGIN_SRC c +double dominant_eigenvalue(Matrix_double *m, Array_double *v, double tolerance, + size_t max_iterations) { + assert(m->rows == m->cols); + assert(m->rows == v->size); + + double error = tolerance; + size_t iter = max_iterations; + double lambda = 0.0; + Array_double *eigenvector_1 = copy_vector(v); + + while (error >= tolerance && (--iter) > 0) { + Array_double *eigenvector_2 = m_dot_v(m, eigenvector_1); + + Array_double *mx = m_dot_v(m, eigenvector_2); + double new_lambda = + v_dot_v(mx, eigenvector_2) / v_dot_v(eigenvector_2, eigenvector_2); + + error = fabs(new_lambda - lambda); + lambda = new_lambda; + free_vector(eigenvector_1); + eigenvector_1 = eigenvector_2; + } + + return lambda; +} +#+END_SRC +*** ~leslie_matrix~ ++ Author: Elizabeth Hunt ++ Name: ~leslie_matrix~ ++ Location: ~src/eigen.c~ ++ Input: two pointers to ~Array_double~'s representing the ratio of individuals in an age class + $x$ getting to the next age class $x+1$ and the number of offspring that individuals in an age + class create in age class 0. ++ Output: the leslie matrix generated with the input vectors. + +#+BEGIN_SRC c +Matrix_double *leslie_matrix(Array_double *age_class_surivor_ratio, + Array_double *age_class_offspring) { + assert(age_class_surivor_ratio->size + 1 == age_class_offspring->size); + + Matrix_double *leslie = InitMatrixWithSize(double, age_class_offspring->size, + age_class_offspring->size, 0.0); + + free_vector(leslie->data[0]); + leslie->data[0] = age_class_offspring; + + for (size_t i = 0; i < age_class_surivor_ratio->size; i++) + leslie->data[i + 1]->data[i] = age_class_surivor_ratio->data[i]; + return leslie; +} +#+END_SRC + ** Appendix / Miscellaneous *** Data Types **** ~Line~ diff --git a/homeworks/hw-7.org b/homeworks/hw-7.org new file mode 100644 index 0000000..bbd0f49 --- /dev/null +++ b/homeworks/hw-7.org @@ -0,0 +1,10 @@ +#+TITLE: Homework 6 +#+AUTHOR: Elizabeth Hunt +#+LATEX_HEADER: \notindent \notag \usepackage{amsmath} \usepackage[a4paper,margin=1in,portrait]{geometry} +#+LATEX: \setlength\parindent{0pt} +#+OPTIONS: toc:nil + +* Question One +See ~UTEST(eigen, dominant_eigenvalue)~ in ~test/eigen.t.c~ and the entry +~Eigen-Adjacent -> dominant_eigenvalue~ in the LIZFCM API documentation. +* Question Two diff --git a/src/eigen.c b/src/eigen.c index 6ea26c3..40b41b8 100644 --- a/src/eigen.c +++ b/src/eigen.c @@ -14,10 +14,8 @@ Matrix_double *leslie_matrix(Array_double *age_class_surivor_ratio, free_vector(leslie->data[0]); leslie->data[0] = age_class_offspring; - for (size_t i = 0; i < age_class_surivor_ratio->size; i++) { + for (size_t i = 0; i < age_class_surivor_ratio->size; i++) leslie->data[i + 1]->data[i] = age_class_surivor_ratio->data[i]; - } - return leslie; } @@ -37,9 +35,9 @@ double dominant_eigenvalue(Matrix_double *m, Array_double *v, double tolerance, Array_double *mx = m_dot_v(m, eigenvector_2); double new_lambda = v_dot_v(mx, eigenvector_2) / v_dot_v(eigenvector_2, eigenvector_2); + error = fabs(new_lambda - lambda); lambda = new_lambda; - free_vector(eigenvector_1); eigenvector_1 = eigenvector_2; }