A <- matrix(c(1,2,0.1, 0.1,1,0.1, 0.1,0.1,0.5), 3,3)
svdDemo(A)
-3D plot
-
-
+3D plot
+
+
if (FALSE) {
B <- matrix(c( 1, 0, 1, 0, 2, 0, 1, 0, 2), 3, 3)
svdDemo(B)
diff --git a/docs/reference/vectors3d.html b/docs/reference/vectors3d.html
index ed51fb12..d0039214 100644
--- a/docs/reference/vectors3d.html
+++ b/docs/reference/vectors3d.html
@@ -188,9 +188,9 @@
diff --git a/docs/search.json b/docs/search.json
index f8b8ca11..6bd3a0d3 100644
--- a/docs/search.json
+++ b/docs/search.json
@@ -1 +1 @@
-[{"path":"http://friendly.github.io/matlib/articles/data-beta.html","id":"data-space","dir":"Articles","previous_headings":"","what":"Data space","title":"Vector Spaces of Least Squares and Linear Equations","text":"start simple linear regression problem, shown data space. Fit linear model, y ~ x. intercept b0 = 2.5 slope b1 = -1. Plot data least squares line.","code":"x <- c(1, 1, -1, -1) y <- 1:4 (mod <- lm(y ~ x)) ## ## Call: ## lm(formula = y ~ x) ## ## Coefficients: ## (Intercept) x ## 2.5 -1.0 par(mar=c(4,4,1,1)+.1) plot(y ~ x, pch=16, cex=1.5) abline(mod, lwd=2) abline(h = coef(mod)[1], col=\"grey\")"},{"path":"http://friendly.github.io/matlib/articles/data-beta.html","id":"linear-equation-beta-space","dir":"Articles","previous_headings":"","what":"Linear equation (\\(\\beta\\)) space","title":"Vector Spaces of Least Squares and Linear Equations","text":"problem can represented matrix equation, \\(\\mathbf{y} = [\\mathbf{1}, \\mathbf{x}] \\mathbf{b} + \\mathbf{e} = \\mathbf{X} \\mathbf{b} + \\mathbf{e}\\). equation form \\(y_i = b_0 + b_1 x_i + e_i\\). least squares solution minimizes \\(\\sum e_i^2\\). can also describe representing four equations two unknowns, c(\"b0\", \"b1\"). equation corresponds line \\((b_0, b_1)\\) space. Let’s plot . plotEqn draws point intersection pair lines — solution pair observations. space, observation equations can satisfied simultaneously, best approximate solution can represented space coefficients linear model \\(y = X \\beta\\), intercept already included first column \\(X\\). LS solution shown black point, corresponding \\((b_0, b_1) = (2.5, -1)\\).","code":"X <- cbind(1, x) printMatEqn(y, \"=\", X, \"*\", vec(c(\"b0\", \"b1\")), \"+\", vec(paste0(\"e\", 1:4))) ## y X ## 1 = 1 1 * b0 + e1 ## 2 1 1 b1 e2 ## 3 1 -1 e3 ## 4 1 -1 e4 showEqn(X, y, vars=c(\"b0\", \"b1\"), simplify=TRUE) ## b0 + b1 = 1 ## b0 + b1 = 2 ## b0 - 1*b1 = 3 ## b0 - 1*b1 = 4 plotEqn(X, y, vars=c(\"b0\", \"b1\"), xlim=c(-2, 4)) ## b0 + b1 = 1 ## b0 + b1 = 2 ## b0 - 1*b1 = 3 ## b0 - 1*b1 = 4 plotEqn(X, y, vars=c(\"b0\", \"b1\"), xlim=c(-2, 4)) ## b0 + b1 = 1 ## b0 + b1 = 2 ## b0 - 1*b1 = 3 ## b0 - 1*b1 = 4 solution <- lm( y ~ 0 + X) loc <- coef(solution) points(x=loc[1], y=loc[2], pch=16, cex=1.5)"},{"path":"http://friendly.github.io/matlib/articles/data-beta.html","id":"observation-space","dir":"Articles","previous_headings":"","what":"Observation space","title":"Vector Spaces of Least Squares and Linear Equations","text":"also third vector space, one coordinate axes refer observations, \\(:n\\), data \\((y_i, x_{i0}, x_{i1}, ...)\\). \\(n\\)-length vectors space relate variables y predictors x1, x2 … . , x0 unit vector, J(n), corresponding intercept model. \\(n\\) observations, space \\(n\\) dimensions. case simple linear regression, fitted values, \\(\\widehat{\\mathbf{y}}\\) correspond projection \\(\\mathbf{y}\\) plane spanned \\(\\mathbf{x_0}, \\mathbf{x_1}\\), yhat <- Proj(y, c(bind(x0, x1))). space, vector residuals, \\(\\mathbf{e}\\) orthogonal complement \\(\\widehat{\\mathbf{y}}\\), .e., \\(\\widehat{\\mathbf{y}} \\perp \\mathbf{e}\\). Another geometrical description residual vector normal vector plane. space corresponds matrix algebra representation linear regression, \\[ \\mathbf{y} = \\mathbf{X} \\widehat{\\mathbf{b}} + \\mathbf{e} = \\widehat{\\mathbf{y}} + \\mathbf{e} \\] fact, least squares solution can derived purely requirement vector \\(\\widehat{\\mathbf{y}}\\) orthogonal vector residuals, \\(\\mathbf{e}\\), .e., \\(\\widehat{\\mathbf{y}}' \\mathbf{e} = 0\\). (margins vignette small give proof assertion.) Observation space can illustrated vector diagram developed , \\(n=3\\) dimensional space, actual data problem. , create x0, x1 y simple example. implies following linear equations, ignoring residuals. display observation space, First create basic 3D plot showing coordinate axes. , use vectors3d() draw vectors x0, x1 y. plane spanned x0, x1 can specified normal vector orthogonal , using new matlib::xprod() function. Finally, use Proj() find projection y plane. plot interactive HTML version. Use mouse wheel expand/contract plot. Drag rotate different view. can also spin plot around ’s axis create movie, isn’t done vignette. comparison, can also show least squares solution data \\(\\beta\\) space. linear equation (\\(\\beta\\)) space.","code":"O <- c(0, 0, 0) # origin x0 <- J(3) # intercept x1 <- c(0, 1, -1) # x y <- c(1, 1, 4) # y y <- 2 * y / floor(len(y)) # make length more convenient for 3D plot X <- cbind(x0, x1) # make a matrix showEqn(X, y, vars=colnames(X), simplify=TRUE) ## x0 = 0.5 ## x0 + x1 = 0.5 ## x0 - 1*x1 = 2 win <- rgl::open3d() # (1) draw observation axes E <- diag(3) rownames(E) <- c(\"1\", \"2\", \"3\") vectors3d(E, lwd=2, color=\"blue\") # (2) draw variable vectors vectors3d(t(X), lwd=2, headlength=0.07) vectors3d(y, labels=c(\"\", \"y\"), color=\"red\", lwd=3, headlength=0.07) # (3) draw the plane spanned by x0, x1 normal <- xprod(x0, x1) rgl::planes3d(normal, col=\"turquoise\", alpha=0.2) # (4) draw projection of y on X py <- Proj(y, X) rgl::segments3d(rbind( y, py)) # draw y to plane rgl::segments3d(rbind( O, py)) # origin to py in the plane corner( O, py, y, d=0.15) # show it's a right angle arc(y, O, py, d=0.2, color=\"red\") play3d(spin3d()) par(mar=c(4,4,1,1)+.1) X <- cbind(x0, x1) plotEqn(X, y, vars=c(\"b0\", \"b1\"), xlim=c(-2, 4)) ## b0 = 0.5 ## b0 + b1 = 0.5 ## b0 - 1*b1 = 2 solution <- lm( y ~ 0 + X) loc <- coef(solution) points(x=loc[1], y=loc[2], pch=16, cex=1.5) abline(v=loc[1], lty=2) abline(h=loc[2], lty=2)"},{"path":"http://friendly.github.io/matlib/articles/data-beta.html","id":"references","dir":"Articles","previous_headings":"","what":"References","title":"Vector Spaces of Least Squares and Linear Equations","text":"Dempster, . P. (1969). Elements Continuous Multivariate Analysis, Addison-Wesley, Fox, J. (1984). Linear Statistical Models Related Methods. NY: John Wiley Sons. Friendly, M.; Monette, G. & Fox, J. (2013). Elliptical Insights: Understanding Statistical Methods Elliptical Geometry Statistical Science, 28, 1-39. Monette, G. (1990). “Geometry Multiple Regression Interactive 3-D Graphics” : Fox, J. & Long, S. (Eds.) Modern Methods Data Analysis, SAGE Publications, 209-256","code":""},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"create-a-2-x-2-matrix","dir":"Articles","previous_headings":"","what":"Create a 2 x 2 matrix","title":"Properties of determinants","text":"","code":"A <- matrix(c(3, 1, 2, 4), nrow=2, byrow=TRUE) A ## [,1] [,2] ## [1,] 3 1 ## [2,] 2 4 det(A) ## [1] 10"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"interchange-two-rows-or-cols-changes-the-sign----1-deta","dir":"Articles","previous_headings":"","what":"1. Interchange two rows or cols changes the sign: -> -1 * det(A)","title":"Properties of determinants","text":"","code":"det(A[ 2:1, ]) ## [1] -10 det(A[, 2:1 ]) ## [1] -10"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"transpose---det-a-unchanged","dir":"Articles","previous_headings":"","what":"2. transpose -> det (A) unchanged","title":"Properties of determinants","text":"","code":"det( t(A) ) ## [1] 10"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"multiply-row-k---k-deta","dir":"Articles","previous_headings":"","what":"3. multiply row * k -> k * det(A)","title":"Properties of determinants","text":"Note multiply rows different constants requires diagonal matrix left.","code":"diag(c(3, 1)) %*% A ## [,1] [,2] ## [1,] 9 3 ## [2,] 2 4 det( diag(c(3, 1)) %*% A) ## [1] 30"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"multiply-matrix-k---k2-deta","dir":"Articles","previous_headings":"","what":"4. multiply matrix * k -> k^2 * det(A)","title":"Properties of determinants","text":"multiplying matrix constant multiplies row.","code":"det(3 * A) ## [1] 90 3^2 * det(A) ## [1] 90"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"det-a-b---deta-detb","dir":"Articles","previous_headings":"","what":"5. det (A B) -> det(A) * det(B)","title":"Properties of determinants","text":"determinant product product determinants. holds number terms matrix product.","code":"B <- matrix(c(4, 2, 3, 5), nrow=2, byrow=TRUE) B ## [,1] [,2] ## [1,] 4 2 ## [2,] 3 5 det(A %*% B) ## [1] 140 det(A) * det(B) ## [1] 140"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"proportional-rows-or-columns---det-0","dir":"Articles","previous_headings":"","what":"6. proportional rows or columns -> det() == 0","title":"Properties of determinants","text":"just add additional copy column 1 matrix, C[,3] == C[,1]. determinant 0 columns linearly dependent.","code":"C <- matrix(c(1, 5, 2, 6, 4, 4), nrow=3, byrow=TRUE) C <- cbind(C, C[,1]) C ## [,1] [,2] [,3] ## [1,] 1 5 1 ## [2,] 2 6 2 ## [3,] 4 4 4 det(C) ## [1] 0"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"add-multiple-of-one-row-to-another---det-unchanged","dir":"Articles","previous_headings":"","what":"7. Add multiple of one row to another -> det unchanged","title":"Properties of determinants","text":"principle behind one elementary row operations.","code":"A[2,] <- A[2,] - 2*A[1,] det(A) ## [1] 10"},{"path":"http://friendly.github.io/matlib/articles/det-ex1.html","id":"geometric-interpretation","dir":"Articles","previous_headings":"","what":"8. Geometric interpretation","title":"Properties of determinants","text":"Many aspects matrices vectors geometric interpretations. \\(2 \\times 2\\) matrices, determinant area parallelogram defined rows (columns), plotted 2D space. (\\(3 \\times 3\\) matrices, determinant volume parallelpiped 3D space.) matlib package handy functions (vectors()) drawing geometric diagrams. simple visual proof fact determinants easiest see case diagonal matrix, row vectors orthogonal, area just height x width. Plot : Finally, can also see determinant zero rows columns proportional. vectors called collinear. enclose area.","code":"A <- matrix(c(3, 1, 2, 4), nrow=2, byrow=TRUE) A ## [,1] [,2] ## [1,] 3 1 ## [2,] 2 4 det(A) ## [1] 10 library(matlib) xlim <- c(0,6) ylim <- c(0,6) par(mar=c(3,3,1,1)+.1) plot(xlim, ylim, type=\"n\", xlab=\"X1\", ylab=\"X2\", asp=1) sum <- A[1,] + A[2,] # draw the parallelogram determined by the rows of A polygon( rbind(c(0,0), A[1,], sum, A[2,]), col=rgb(1,0,0,.2)) vectors(A, labels=c(\"a1\", \"a2\"), pos.lab=c(4,2)) vectors(sum, origin=A[1,], col=\"gray\") vectors(sum, origin=A[2,], col=\"gray\") # add some annotations text(0,6, \"det(A) is the area of its row vectors\", pos=4) text(mean(A[,1]), mean(A[,2]), \"det(A)\", cex=1.25) (D <- 2 * diag(2)) ## [,1] [,2] ## [1,] 2 0 ## [2,] 0 2 det(D) ## [1] 4 par(mar=c(3,3,1,1)+.1) plot(c(0,2), c(0,2), type=\"n\", xlab=\"X1\", ylab=\"X2\", asp=1) sum <- D[1,] + D[2,] polygon( rbind(c(0,0), D[1,], sum, D[2,]), col=rgb(0,1,0,.2)) vectors(D, labels=c(\"d1\", \"d2\"), pos.lab=c(3,4)) vectors(sum, origin=D[1,], col=\"gray\") vectors(sum, origin=D[2,], col=\"gray\") text(mean(D[,1]), mean(D[,2]), \"det(D)\", cex=1.25) (B <- matrix(c(1, 2, 2, 4), 2,2)) ## [,1] [,2] ## [1,] 1 2 ## [2,] 2 4 det(B) ## [1] 0 par(mar=c(3,3,1,1)+.1) plot(c(0,4), c(0,4), type=\"n\", xlab=\"X1\", ylab=\"X2\", asp=1) vectors(B, labels=c(\"b1\", \"b2\"), pos.lab=c(4,2))"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"calculate-det-by-cofactor-expansion","dir":"Articles","previous_headings":"","what":"1. Calculate det() by cofactor expansion","title":"Evaluation of determinants","text":"Set \\(3 \\times 3\\) matrix, find determinant (know answer ).","code":"A <- matrix(c(4, 2, 1, 5, 6, 7, 1, 0, 3), nrow=3, byrow=TRUE) det(A) ## [1] 50"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"find-cofactors-of-row-1-elements","dir":"Articles","previous_headings":"1. Calculate det() by cofactor expansion","what":"Find cofactors of row 1 elements","title":"Evaluation of determinants","text":"cofactor \\(A_{,j}\\) element \\(a_{,j}\\) signed determinant left row , column j matrix \\(\\) deleted. NB: R, negative subscripts delete rows columns.","code":"cat(cofactor(A, 1, 1), \" == \", 1 * det( (A[-1, -1]), \"\\n\" )) ## 18 == 18 cat(cofactor(A, 1, 2), \" == \", -1 * det( (A[-1, -2]), \"\\n\" )) ## -8 == -8 cat(cofactor(A, 1, 3), \" == \", 1 * det( (A[-1, -3]), \"\\n\" )) ## -6 == -6"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"det-product-of-row-with-cofactors","dir":"Articles","previous_headings":"1. Calculate det() by cofactor expansion","what":"det() = product of row with cofactors","title":"Evaluation of determinants","text":"symbols: \\(\\det() = a_{1,1} * A_{1,1} + a_{1,2} * A_{1,2} + a_{1,3} * A_{1,3}\\) rowCofactors() convenience function, calculates together Voila: Multiply row 1 times cofactors elements. NB: R, multiplication gives \\(1 \\times 1\\) matrix.","code":"rowCofactors(A, 1) ## [1] 18 -8 -6 A[1,] %*% rowCofactors(A, 1) ## [,1] ## [1,] 50 all.equal( det(A), c(A[1,] %*% rowCofactors(A, 1)) ) ## [1] TRUE"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"finding-det-by-gaussian-elimination-pivoting","dir":"Articles","previous_headings":"","what":"2. Finding det() by Gaussian elimination (pivoting)","title":"Evaluation of determinants","text":"example follows Green Carroll, Table 2.2. Start 4 x 4 matrix, \\(M\\), save det(M). det() product ‘pivots’, leading diagonal elements. step reduces row 1 column 1 0, may discarded. NB: R, dropping row/column can change matrix vector, use drop = FALSE inside subscript.","code":"M <- matrix(c(2, 3, 1, 2, 4, 2, 3, 4, 1, 4, 2, 2, 3, 1, 0, 1), nrow=4, ncol=4, byrow=TRUE) (dsave <- det(M)) ## [1] 15 # ### 'pivot' on the leading diagonal element, M[1,1]: (d <- M[1,1]) ## [1] 2 #-- Reduce row 1, col 1 to 0 (M[1,] <- M[1,, drop=FALSE] / M[1, 1]) ## [,1] [,2] [,3] [,4] ## [1,] 1 1.5 0.5 1 (M <- M - M[,1] %*% M[1,, drop=FALSE]) ## [,1] [,2] [,3] [,4] ## [1,] 0 0.0 0.0 0 ## [2,] 0 -4.0 1.0 0 ## [3,] 0 2.5 1.5 1 ## [4,] 0 -3.5 -1.5 -2 #-- Drop first row and column M <- M[-1, -1] #-- Accumulate the product of pivots d <- d * M[1, 1]"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"repeat-reducing-new-row-col-1-to-0","dir":"Articles","previous_headings":"2. Finding det() by Gaussian elimination (pivoting)","what":"Repeat, reducing new row, col 1 to 0","title":"Evaluation of determinants","text":"","code":"(M[1,] <- M[1,, drop=FALSE] / M[1,1]) ## [,1] [,2] [,3] ## [1,] 1 -0.25 0 (M <- M - M[,1] %*% M[1,, drop=FALSE]) ## [,1] [,2] [,3] ## [1,] 0 0.000 0 ## [2,] 0 2.125 1 ## [3,] 0 -2.375 -2 M <- M[-1, -1] d = d * M[1, 1]"},{"path":"http://friendly.github.io/matlib/articles/det-ex2.html","id":"repeat-once-more--d-detm","dir":"Articles","previous_headings":"2. Finding det() by Gaussian elimination (pivoting)","what":"Repeat once more. d = det(M)","title":"Evaluation of determinants","text":"","code":"(M[1,] <- M[1,, drop=FALSE] / M[1,1]) ## [,1] [,2] ## [1,] 1 0.4706 (M <- M - M[,1] %*% M[1,, drop=FALSE]) ## [,1] [,2] ## [1,] 0 0.0000 ## [2,] 0 -0.8824 M <- M[-1, -1, drop=FALSE] d <- d * M[1, 1] # did we get it right? all.equal(d, dsave) ## [1] TRUE"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex1.html","id":"setup","dir":"Articles","previous_headings":"","what":"Setup","title":"Eigenvalues and Eigenvectors: Properties","text":"vignette uses example \\(3 \\times 3\\) matrix illustrate properties eigenvalues eigenvectors. consider variance-covariance matrix three variables, main thing matrix square symmetric, guarantees eigenvalues, \\(\\lambda_i\\) real numbers. Covariance matrices also positive semi-definite, meaning eigenvalues non-negative, \\(\\lambda_i \\ge 0\\). Get eigenvalues eigenvectors using eigen(); returns named list, eigenvalues named values eigenvectors named vectors. eigenvalues always returned decreasing order, column vectors corresponds elements values.","code":"A <- matrix(c(13, -4, 2, -4, 11, -2, 2, -2, 8), 3, 3, byrow=TRUE) A ## [,1] [,2] [,3] ## [1,] 13 -4 2 ## [2,] -4 11 -2 ## [3,] 2 -2 8 ev <- eigen(A) # extract components (values <- ev$values) ## [1] 17 8 7 (vectors <- ev$vectors) ## [,1] [,2] [,3] ## [1,] 0.7454 0.6667 0.0000 ## [2,] -0.5963 0.6667 0.4472 ## [3,] 0.2981 -0.3333 0.8944"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex1.html","id":"properties-of-eigenvalues-and-eigenvectors","dir":"Articles","previous_headings":"","what":"Properties of eigenvalues and eigenvectors","title":"Eigenvalues and Eigenvectors: Properties","text":"following steps illustrate main properties eigenvalues eigenvectors. use notation \\(= V' \\Lambda V\\) express decomposition matrix \\(\\), \\(V\\) matrix eigenvectors \\(\\Lambda = diag(\\lambda_1, \\lambda_2, \\dots, \\lambda_p)\\) diagonal matrix composed ordered eivenvalues, \\(\\lambda_1 \\ge \\lambda_2 \\ge \\dots \\lambda_p\\). Orthogonality: Eigenvectors always orthogonal, \\(V' V = \\). zapsmall() handy cleaning tiny values. trace() = sum eigenvalues, \\(\\sum \\lambda_i\\). sum squares = sum squares eigenvalues, \\(\\sum \\lambda_i^2\\). determinant = product eigenvalues, \\(det() = \\prod \\lambda_i\\). means determinant zero \\(\\lambda_i = 0\\). rank = number non-zero eigenvalues eigenvalues \\(^{-1}\\) = 1/eigenvalues . eigenvectors , except order, eigenvalues returned decreasing order. similar relations powers matrix: values(mpower(,p)) = values()^p, mpower(,2) = %*% , etc.","code":"crossprod(vectors) ## [,1] [,2] [,3] ## [1,] 1.000e+00 3.053e-16 5.551e-17 ## [2,] 3.053e-16 1.000e+00 0.000e+00 ## [3,] 5.551e-17 0.000e+00 1.000e+00 zapsmall(crossprod(vectors)) ## [,1] [,2] [,3] ## [1,] 1 0 0 ## [2,] 0 1 0 ## [3,] 0 0 1 library(matlib) # use the matlib package tr(A) ## [1] 32 sum(values) ## [1] 32 sum(A^2) ## [1] 402 sum(values^2) ## [1] 402 det(A) ## [1] 952 prod(values) ## [1] 952 R(A) ## [1] 3 sum(values != 0) ## [1] 3 AI <- solve(A) AI ## [,1] [,2] [,3] ## [1,] 0.08824 0.02941 -0.01471 ## [2,] 0.02941 0.10504 0.01891 ## [3,] -0.01471 0.01891 0.13340 eigen(AI)$values ## [1] 0.14286 0.12500 0.05882 eigen(AI)$vectors ## [,1] [,2] [,3] ## [1,] 0.0000 0.6667 0.7454 ## [2,] 0.4472 0.6667 -0.5963 ## [3,] 0.8944 -0.3333 0.2981 eigen(A %*% A) ## eigen() decomposition ## $values ## [1] 289 64 49 ## ## $vectors ## [,1] [,2] [,3] ## [1,] 0.7454 0.6667 0.0000 ## [2,] -0.5963 0.6667 0.4472 ## [3,] 0.2981 -0.3333 0.8944 eigen(A %*% A %*% A)$values ## [1] 4913 512 343 eigen(mpower(A, 4))$values ## [1] 83521 4096 2401"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex2.html","id":"setup","dir":"Articles","previous_headings":"","what":"Setup","title":"Eigenvalues: Spectral Decomposition","text":"vignette uses example \\(3 \\times 3\\) matrix illustrate properties eigenvalues eigenvectors. consider variance-covariance matrix three variables, main thing matrix square symmetric, guarantees eigenvalues, \\(\\lambda_i\\) real numbers, non-negative, \\(\\lambda_i \\ge 0\\). Get eigenvalues eigenvectors using eigen(); returns named list, eigenvalues named values eigenvectors named vectors. call L V , formulas correspond diagonal matrix, \\(\\mathbf{\\Lambda} = diag(\\lambda_1, \\lambda_2, \\lambda_3)\\), (orthogonal) matrix \\(\\mathbf{V}\\).","code":"A <- matrix(c(13, -4, 2, -4, 11, -2, 2, -2, 8), 3, 3, byrow=TRUE) A ## [,1] [,2] [,3] ## [1,] 13 -4 2 ## [2,] -4 11 -2 ## [3,] 2 -2 8 ev <- eigen(A) # extract components (L <- ev$values) ## [1] 17 8 7 (V <- ev$vectors) ## [,1] [,2] [,3] ## [1,] 0.7454 0.6667 0.0000 ## [2,] -0.5963 0.6667 0.4472 ## [3,] 0.2981 -0.3333 0.8944"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex2.html","id":"matrix-factorization","dir":"Articles","previous_headings":"","what":"Matrix factorization","title":"Eigenvalues: Spectral Decomposition","text":"Factorization : = V diag(L) V’. , matrix \\(\\mathbf{}\\) can represented product \\(\\mathbf{}= \\mathbf{V} \\mathbf{\\Lambda} \\mathbf{V}'\\). V diagonalizes : L = V’ V. , matrix \\(\\mathbf{V}\\) transforms \\(\\mathbf{}\\) diagonal matrix \\(\\mathbf{\\Lambda}\\), corresponding orthogonal (uncorrelated) variables.","code":"V %*% diag(L) %*% t(V) ## [,1] [,2] [,3] ## [1,] 13 -4 2 ## [2,] -4 11 -2 ## [3,] 2 -2 8 diag(L) ## [,1] [,2] [,3] ## [1,] 17 0 0 ## [2,] 0 8 0 ## [3,] 0 0 7 zapsmall(t(V) %*% A %*% V) ## [,1] [,2] [,3] ## [1,] 17 0 0 ## [2,] 0 8 0 ## [3,] 0 0 7"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex2.html","id":"spectral-decomposition","dir":"Articles","previous_headings":"","what":"Spectral decomposition","title":"Eigenvalues: Spectral Decomposition","text":"basic idea eigenvalue–eigenvector pair generates rank 1 matrix, \\(\\lambda_i \\mathbf{v}_i \\mathbf{v}_i '\\), sum original matrix, \\(\\mathbf{} = \\sum_i \\lambda_i \\mathbf{v}_i \\mathbf{v}_i '\\). , summing gives , decompose :","code":"A1 = L[1] * V[,1] %*% t(V[,1]) A1 ## [,1] [,2] [,3] ## [1,] 9.444 -7.556 3.778 ## [2,] -7.556 6.044 -3.022 ## [3,] 3.778 -3.022 1.511 A2 = L[2] * V[,2] %*% t(V[,2]) A2 ## [,1] [,2] [,3] ## [1,] 3.556 3.556 -1.7778 ## [2,] 3.556 3.556 -1.7778 ## [3,] -1.778 -1.778 0.8889 A3 = L[3] * V[,3] %*% t(V[,3]) A3 ## [,1] [,2] [,3] ## [1,] 0 0.0 0.0 ## [2,] 0 1.4 2.8 ## [3,] 0 2.8 5.6 A1 + A2 + A3 ## [,1] [,2] [,3] ## [1,] 13 -4 2 ## [2,] -4 11 -2 ## [3,] 2 -2 8 all.equal(A, A1+A2+A3) ## [1] TRUE"},{"path":"http://friendly.github.io/matlib/articles/eigen-ex2.html","id":"further-properties","dir":"Articles","previous_headings":"Spectral decomposition","what":"Further properties","title":"Eigenvalues: Spectral Decomposition","text":"Sum squares = sum sum squares A1, A2, A3 squared eigenvalue gives sum squares accounted latent vector first \\(\\) eigenvalues vectors give rank \\(\\) approximation ","code":"sum(A^2) ## [1] 402 c( sum(A1^2), sum(A2^2), sum(A3^2) ) ## [1] 289 64 49 sum( sum(A1^2), sum(A2^2), sum(A3^2) ) ## [1] 402 #' same as tr(A' A) tr(crossprod(A)) ## [1] 402 L^2 ## [1] 289 64 49 cumsum(L^2) # cumulative ## [1] 289 353 402 R(A1) ## [1] 1 R(A1 + A2) ## [1] 2 R(A1 + A2 + A3) ## [1] 3 # two dimensions sum((A1+A2)^2) ## [1] 353 sum((A1+A2)^2) / sum(A^2) # proportion ## [1] 0.8781"},{"path":"http://friendly.github.io/matlib/articles/ginv.html","id":"properties-of-generalized-inverse-moore-penrose-inverse","dir":"Articles","previous_headings":"","what":"Properties of generalized inverse (Moore-Penrose inverse)","title":"Generalized inverse","text":"generalized inverse defined matrix \\(^-\\) \\(* ^- * = \\) \\(^- * * ^- = ^-\\) addition, \\(* ^-\\) \\(^- * \\) symmetric, neither product gives identity matrix, %*% AI != AI %*% != ","code":"A %*% AI %*% A ## [,1] [,2] [,3] ## [1,] 4 4 -2 ## [2,] 4 4 -2 ## [3,] -2 -2 10 AI %*% A %*% AI ## [,1] [,2] [,3] ## [1,] 0.27778 0 0.05556 ## [2,] 0.00000 0 0.00000 ## [3,] 0.05556 0 0.11111 zapsmall(A %*% AI) ## [,1] [,2] [,3] ## [1,] 1 0 0 ## [2,] 1 0 0 ## [3,] 0 0 1 zapsmall(AI %*% A) ## [,1] [,2] [,3] ## [1,] 1 1 0 ## [2,] 0 0 0 ## [3,] 0 0 1"},{"path":"http://friendly.github.io/matlib/articles/ginv.html","id":"rectangular-matrices","dir":"Articles","previous_headings":"","what":"Rectangular matrices","title":"Generalized inverse","text":"rectangular matrix, \\(^- = (^{T} )^{-1} ^{T}\\) generalized inverse \\(\\) \\((^{T} )^-\\) ginv \\((^{T} )\\) [See: Timm: EX 1.6.11] \\(4 \\times 3\\) matrix full rank, columns 2 3 sum column 1. generalized inverse \\(\\) \\((^{T} )^- ^{T}\\), AAI * t() Show generalized inverse:","code":"A <- cbind( 1, matrix(c(1, 0, 1, 0, 0, 1, 0, 1), nrow=4, byrow=TRUE)) A ## [,1] [,2] [,3] ## [1,] 1 1 0 ## [2,] 1 1 0 ## [3,] 1 0 1 ## [4,] 1 0 1 R(A) ## [1] 2 (AA <- t(A) %*% A) ## [,1] [,2] [,3] ## [1,] 4 2 2 ## [2,] 2 2 0 ## [3,] 2 0 2 (AAI <- Ginv(AA)) ## [,1] [,2] [,3] ## [1,] 0.5 -0.5 0 ## [2,] -0.5 1.0 0 ## [3,] 0.0 0.0 0 AI <- AAI %*% t(A) A %*% AI %*% A ## [,1] [,2] [,3] ## [1,] 1 1 0 ## [2,] 1 1 0 ## [3,] 1 0 1 ## [4,] 1 0 1 AI %*% A %*% AI ## [,1] [,2] [,3] [,4] ## [1,] 0.0 0.0 0.5 0.5 ## [2,] 0.5 0.5 -0.5 -0.5 ## [3,] 0.0 0.0 0.0 0.0"},{"path":"http://friendly.github.io/matlib/articles/gramreg.html","id":"setup","dir":"Articles","previous_headings":"","what":"Setup","title":"Gram-Schmidt Orthogonalization and Regression","text":"use class data set, convert character factor sex dummy (0/1) variable male. later use regression, create variable IQ response variable Reorder predictors want, forming numeric matrix, X.","code":"library(matlib) data(class) class$male <- as.numeric(class$sex==\"M\") class <- transform(class, IQ = round(20 + height + 3*age -.1*weight -3*male + 10*rnorm(nrow(class)))) head(class) ## sex age height weight male IQ ## Alfred M 14 69.0 112.5 1 115 ## Alice F 13 56.5 84.0 0 104 ## Barbara F 13 65.3 98.0 0 112 ## Carol F 14 62.8 102.5 0 105 ## Henry M 14 63.5 102.5 1 110 ## James M 12 57.3 83.0 1 93 X <- as.matrix(class[,c(3,4,2,5)]) head(X) ## height weight age male ## Alfred 69.0 112.5 14 1 ## Alice 56.5 84.0 13 0 ## Barbara 65.3 98.0 13 0 ## Carol 62.8 102.5 14 0 ## Henry 63.5 102.5 14 1 ## James 57.3 83.0 12 1"},{"path":"http://friendly.github.io/matlib/articles/gramreg.html","id":"orthogonalization-by-projections","dir":"Articles","previous_headings":"","what":"Orthogonalization by projections","title":"Gram-Schmidt Orthogonalization and Regression","text":"Gram-Schmidt process treats variables given order, according columns X. start new matrix Z consisting X[,1]. , find new variable Z[,2] orthogonal Z[,1] subtracting projection X[,2] Z[,1]. Continue way, subtracting projections X[,3] previous columns, forth Note column X linear combination previous columns, corresponding column Z zeros. computations similar following set linear regressions: columns Z now orthogonal, unit length, make standardize column unit length, giving Z orthonormal matrix, \\(Z' Z = \\).","code":"Z <- cbind(X[,1], 0, 0, 0) Z[,2] <- X[,2] - Proj(X[,2], Z[,1]) crossprod(Z[,1], Z[,2]) # verify orthogonality ## [,1] ## [1,] 7.276e-12 Z[,3] <- X[,3] - Proj(X[,3], Z[,1]) - Proj(X[,3], Z[,2]) Z[,4] <- X[,4] - Proj(X[,4], Z[,1]) - Proj(X[,4], Z[,2]) - Proj(X[,4], Z[,3]) z2 <- residuals(lm(X[,2] ~ X[,1]), type=\"response\") z3 <- residuals(lm(X[,3] ~ X[,1:2]), type=\"response\") z4 <- residuals(lm(X[,4] ~ X[,1:3]), type=\"response\") zapsmall(crossprod(Z)) # check orthogonality ## [,1] [,2] [,3] [,4] ## [1,] 57888 0 0 0 ## [2,] 0 3249 0 0 ## [3,] 0 0 7 0 ## [4,] 0 0 0 2 Z <- Z %*% diag(1 / len(Z)) # make each column unit length zapsmall(crossprod(Z)) # check orthonormal ## [,1] [,2] [,3] [,4] ## [1,] 1 0 0 0 ## [2,] 0 1 0 0 ## [3,] 0 0 1 0 ## [4,] 0 0 0 1 colnames(Z) <- colnames(X)"},{"path":"http://friendly.github.io/matlib/articles/gramreg.html","id":"relationship-to-qr-factorization","dir":"Articles","previous_headings":"Orthogonalization by projections","what":"Relationship to QR factorization","title":"Gram-Schmidt Orthogonalization and Regression","text":"QR method uses essentially process, factoring matrix \\(\\mathbf{X}\\) \\(\\mathbf{X = Q R}\\), \\(\\mathbf{Q}\\) orthonormal matrix corresponding Z \\(\\mathbf{R}\\) upper triangular matrix. However, signs columns \\(\\mathbf{Q}\\) arbitrary, QR() returns QR(X)$Q signs reversed, compared Z.","code":"# same result as QR(X)$Q, but with signs reversed head(Z, 5) ## height weight age male ## Alfred 0.2868 0.07545 -0.3687 0.12456 ## Alice 0.2348 -0.08067 0.3569 -0.02177 ## Barbara 0.2714 -0.07715 -0.3862 -0.45170 ## Carol 0.2610 0.07058 0.1559 -0.20548 ## Henry 0.2639 0.05132 0.1047 0.40538 head(-QR(X)$Q, 5) ## [,1] [,2] [,3] [,4] ## [1,] 0.2868 0.07545 -0.3687 0.12456 ## [2,] 0.2348 -0.08067 0.3569 -0.02177 ## [3,] 0.2714 -0.07715 -0.3862 -0.45170 ## [4,] 0.2610 0.07058 0.1559 -0.20548 ## [5,] 0.2639 0.05132 0.1047 0.40538 all.equal( unname(Z), -QR(X)$Q ) ## [1] TRUE"},{"path":"http://friendly.github.io/matlib/articles/gramreg.html","id":"regression-with-x-and-z","dir":"Articles","previous_headings":"","what":"Regression with X and Z","title":"Gram-Schmidt Orthogonalization and Regression","text":"carry two regressions IQ variables X Z. equivalent, sense \\(R^2\\) MSE models Residuals Type tests given anova() . Regression IQ original variables X Regression IQ orthogonalized variables Z illustrates anova() tests linear models sequential tests. test hypotheses extra contribution variable previous ones, given order. usually make substantive sense, except testing ordered (“hierarchical”) models.","code":"class2 <- data.frame(Z, IQ=class$IQ) mod1 <- lm(IQ ~ height + weight + age + male, data=class) anova(mod1) ## Analysis of Variance Table ## ## Response: IQ ## Df Sum Sq Mean Sq F value Pr(>F) ## height 1 389 389 6.08 0.033 * ## weight 1 196 196 3.07 0.110 ## age 1 82 82 1.28 0.284 ## male 1 12 12 0.18 0.678 ## Residuals 10 639 64 ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 mod2 <- lm(IQ ~ height + weight + age + male, data=class2) anova(mod2) ## Analysis of Variance Table ## ## Response: IQ ## Df Sum Sq Mean Sq F value Pr(>F) ## height 1 389 389 6.08 0.033 * ## weight 1 196 196 3.07 0.110 ## age 1 82 82 1.28 0.284 ## male 1 12 12 0.18 0.678 ## Residuals 10 639 64 ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"load-the-matlib-package","dir":"Articles","previous_headings":"","what":"Load the matlib package","title":"Inverse of a matrix","text":"defines: inv(), Inverse(); standard R function matrix inverse solve()","code":"library(matlib)"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"create-a-3-x-3-matrix","dir":"Articles","previous_headings":"","what":"Create a 3 x 3 matrix","title":"Inverse of a matrix","text":"ordinary inverse defined square matrices.","code":"A <- matrix( c(5, 1, 0, 3,-1, 2, 4, 0,-1), nrow=3, byrow=TRUE) det(A) ## [1] 16"},{"path":[]},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"deta-0-so-inverse-exists","dir":"Articles","previous_headings":"Basic properties","what":"1. det(A) != 0, so inverse exists","title":"Inverse of a matrix","text":"non-singular matrices inverse.","code":"(AI <- inv(A)) ## [,1] [,2] [,3] ## [1,] 0.0625 0.0625 0.125 ## [2,] 0.6875 -0.3125 -0.625 ## [3,] 0.2500 0.2500 -0.500"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"definition-of-the-inverse-a-1-a-a-a-1-i-or-ai-a-diagnrowa","dir":"Articles","previous_headings":"Basic properties","what":"2. Definition of the inverse: \\(A^{-1} A = A A^{-1} = I\\) or AI * A = diag(nrow(A))","title":"Inverse of a matrix","text":"inverse matrix \\(\\) defined matrix \\(^{-1}\\) multiplies \\(\\) give identity matrix, just , scalar \\(\\), \\(^{-1} = / = 1\\). NB: Sometimes get tiny -diagonal values (like 1.341e-13). function zapsmall() round 0.","code":"AI %*% A ## [,1] [,2] [,3] ## [1,] 1 0 0 ## [2,] 0 1 0 ## [3,] 0 0 1"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-is-reflexive-invinva-a","dir":"Articles","previous_headings":"Basic properties","what":"3. Inverse is reflexive: inv(inv(A)) = A","title":"Inverse of a matrix","text":"Taking inverse twice gets back started.","code":"inv(AI) ## [,1] [,2] [,3] ## [1,] 5 1 0 ## [2,] 3 -1 2 ## [3,] 4 0 -1"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inva-is-symmetric-if-and-only-if-a-is-symmetric","dir":"Articles","previous_headings":"Basic properties","what":"4. inv(A) is symmetric if and only if A is symmetric","title":"Inverse of a matrix","text":"symmetric case:","code":"inv( t(A) ) ## [,1] [,2] [,3] ## [1,] 0.0625 0.6875 0.25 ## [2,] 0.0625 -0.3125 0.25 ## [3,] 0.1250 -0.6250 -0.50 is_symmetric_matrix(A) ## [1] FALSE is_symmetric_matrix( inv( t(A) ) ) ## [1] FALSE B <- matrix( c(4, 2, 2, 2, 3, 1, 2, 1, 3), nrow=3, byrow=TRUE) inv(B) ## [,1] [,2] [,3] ## [1,] 0.50 -0.25 -0.25 ## [2,] -0.25 0.50 0.00 ## [3,] -0.25 0.00 0.50 inv( t(B) ) ## [,1] [,2] [,3] ## [1,] 0.50 -0.25 -0.25 ## [2,] -0.25 0.50 0.00 ## [3,] -0.25 0.00 0.50 is_symmetric_matrix(B) ## [1] TRUE is_symmetric_matrix( inv( t(B) ) ) ## [1] TRUE all.equal( inv(B), inv( t(B) ) ) ## [1] TRUE"},{"path":[]},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-of-diagonal-matrix-diag-1-diagonal","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"1. inverse of diagonal matrix = diag( 1/ diagonal)","title":"Inverse of a matrix","text":"simple examples, often useful show results matrix calculations fractions, using MASS::fractions().","code":"D <- diag(c(1, 2, 4)) inv(D) ## [,1] [,2] [,3] ## [1,] 1 0.0 0.00 ## [2,] 0 0.5 0.00 ## [3,] 0 0.0 0.25 MASS::fractions( diag(1 / c(1, 2, 4)) ) ## [,1] [,2] [,3] ## [1,] 1 0 0 ## [2,] 0 1/2 0 ## [3,] 0 0 1/4"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-of-an-inverse-invinva-a","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"2. Inverse of an inverse: inv(inv(A)) = A","title":"Inverse of a matrix","text":"","code":"A <- matrix(c(1, 2, 3, 2, 3, 0, 0, 1, 2), nrow=3, byrow=TRUE) AI <- inv(A) inv(AI) ## [,1] [,2] [,3] ## [1,] 1 2 3 ## [2,] 2 3 0 ## [3,] 0 1 2"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-of-a-transpose-invta-tinva","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"3. inverse of a transpose: inv(t(A)) = t(inv(A))","title":"Inverse of a matrix","text":"","code":"inv( t(A) ) ## [,1] [,2] [,3] ## [1,] 1.50 -1.0 0.50 ## [2,] -0.25 0.5 -0.25 ## [3,] -2.25 1.5 -0.25 t( inv(A) ) ## [,1] [,2] [,3] ## [1,] 1.50 -1.0 0.50 ## [2,] -0.25 0.5 -0.25 ## [3,] -2.25 1.5 -0.25"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-of-a-scalar-matrix-inv-ka-1k-inva","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"4. inverse of a scalar * matrix: inv( k*A ) = (1/k) * inv(A)","title":"Inverse of a matrix","text":"","code":"inv(5 * A) ## [,1] [,2] [,3] ## [1,] 0.3 -0.05 -0.45 ## [2,] -0.2 0.10 0.30 ## [3,] 0.1 -0.05 -0.05 (1/5) * inv(A) ## [,1] [,2] [,3] ## [1,] 0.3 -0.05 -0.45 ## [2,] -0.2 0.10 0.30 ## [3,] 0.1 -0.05 -0.05"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"inverse-of-a-matrix-product-inva-b-invb-inva","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"5. inverse of a matrix product: inv(A * B) = inv(B) %*% inv(A)","title":"Inverse of a matrix","text":"extends number terms: inverse product product inverses reverse order.","code":"B <- matrix(c(1, 2, 3, 1, 3, 2, 2, 4, 1), nrow=3, byrow=TRUE) C <- B[, 3:1] A %*% B ## [,1] [,2] [,3] ## [1,] 9 20 10 ## [2,] 5 13 12 ## [3,] 5 11 4 inv(A %*% B) ## [,1] [,2] [,3] ## [1,] 4.0 -1.50 -5.50 ## [2,] -2.0 0.70 2.90 ## [3,] 0.5 -0.05 -0.85 inv(B) %*% inv(A) ## [,1] [,2] [,3] ## [1,] 4.0 -1.50 -5.50 ## [2,] -2.0 0.70 2.90 ## [3,] 0.5 -0.05 -0.85 (ABC <- A %*% B %*% C) ## [,1] [,2] [,3] ## [1,] 77 118 49 ## [2,] 53 97 42 ## [3,] 41 59 24 inv(A %*% B %*% C) ## [,1] [,2] [,3] ## [1,] 1.5 -0.59 -2.03 ## [2,] -4.5 1.61 6.37 ## [3,] 8.5 -2.95 -12.15 inv(C) %*% inv(B) %*% inv(A) ## [,1] [,2] [,3] ## [1,] 1.5 -0.59 -2.03 ## [2,] -4.5 1.61 6.37 ## [3,] 8.5 -2.95 -12.15 inv(ABC) ## [,1] [,2] [,3] ## [1,] 1.5 -0.59 -2.03 ## [2,] -4.5 1.61 6.37 ## [3,] 8.5 -2.95 -12.15"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"det-a-1-1-deta-deta-1","dir":"Articles","previous_headings":"More properties of matrix inverse","what":"6. \\(\\det (A^{-1}) = 1 / \\det(A) = [\\det(A)]^{-1}\\)","title":"Inverse of a matrix","text":"determinant inverse inverse (reciprocal) determinant","code":"det(AI) ## [1] 0.25 1 / det(A) ## [1] 0.25"},{"path":"http://friendly.github.io/matlib/articles/inv-ex1.html","id":"geometric-interpretations","dir":"Articles","previous_headings":"","what":"Geometric interpretations","title":"Inverse of a matrix","text":"properties matrix inverse can easily understood geometric diagrams. , take \\(2 \\times 2\\) non-singular matrix \\(\\), larger determinant \\(\\), smaller determinant \\(^{-1}\\). Now, plot rows \\(\\) vectors \\(a_1, a_2\\) origin 2D space. illustrated vignette(\"det-ex1\"), area parallelogram defined vectors determinant. rows inverse \\(^{-1}\\) can shown vectors \\(^1, ^2\\) origin space. Thus, can see: shape \\(^{-1}\\) \\(90^o\\) rotation shape \\(\\). \\(^{-1}\\) small directions \\(\\) large. vector \\(^2\\) right angles \\(a_1\\) \\(^1\\) right angles \\(a_2\\) multiplied \\(\\) constant \\(k\\) make determinant larger (factor \\(k^2\\)), inverse divided factor preserve \\(^{-1} = \\). One might wonder whether properties depend symmetry \\(\\), another example, matrix <- matrix(c(2, 1, 1, 1), nrow=2), \\(\\det()=1\\). areas two parallelograms \\(\\det() = \\det(^{-1}) = 1\\).","code":"A <- matrix(c(2, 1, 1, 2), nrow=2, byrow=TRUE) A ## [,1] [,2] ## [1,] 2 1 ## [2,] 1 2 det(A) ## [1] 3 AI <- inv(A) MASS::fractions(AI) ## [,1] [,2] ## [1,] 2/3 -1/3 ## [2,] -1/3 2/3 det(AI) ## [1] 0.3333 par(mar=c(3,3,1,1)+.1) xlim <- c(-1,3) ylim <- c(-1,3) plot(xlim, ylim, type=\"n\", xlab=\"X1\", ylab=\"X2\", asp=1) sum <- A[1,] + A[2,] # draw the parallelogram determined by the rows of A polygon( rbind(c(0,0), A[1,], sum, A[2,]), col=rgb(1,0,0,.2)) vectors(A, labels=c(expression(a[1]), expression(a[2])), pos.lab=c(4,2)) vectors(sum, origin=A[1,], col=\"gray\") vectors(sum, origin=A[2,], col=\"gray\") text(mean(A[,1]), mean(A[,2]), \"A\", cex=1.5) vectors(AI, labels=c(expression(a^1), expression(a^2)), pos.lab=c(4,2)) sum <- AI[1,] + AI[2,] polygon( rbind(c(0,0), AI[1,], sum, AI[2,]), col=rgb(0,0,1,.2)) text(mean(AI[,1])-.3, mean(AI[,2])-.2, expression(A^{-1}), cex=1.5) (A <- matrix(c(2, 1, 1, 1), nrow=2)) ## [,1] [,2] ## [1,] 2 1 ## [2,] 1 1 (AI <- inv(A)) ## [,1] [,2] ## [1,] 1 -1 ## [2,] -1 2"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"load-the-matlib-package","dir":"Articles","previous_headings":"","what":"Load the matlib package","title":"Matrix inversion by elementary row operations","text":"","code":"library(matlib)"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"create-a-3-x-3-matrix","dir":"Articles","previous_headings":"","what":"Create a 3 x 3 matrix","title":"Matrix inversion by elementary row operations","text":"","code":"A <- matrix( c(1, 2, 3, 2, 3, 0, 0, 1,-2), nrow=3, byrow=TRUE)"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"join-an-identity-matrix-to-a","dir":"Articles","previous_headings":"","what":"Join an identity matrix to A","title":"Matrix inversion by elementary row operations","text":"","code":"(AI <- cbind(A, diag(3))) ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 2 3 1 0 0 ## [2,] 2 3 0 0 1 0 ## [3,] 0 1 -2 0 0 1"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"apply-elementary-row-operations-to-reduce-a-to-an-identity-matrix-","dir":"Articles","previous_headings":"","what":"Apply elementary row operations to reduce A to an identity matrix.","title":"Matrix inversion by elementary row operations","text":"right three cols contain inv(). three ways: first, just using R arithmetic rows AI using ERO functions matlib package using echelon() function","code":""},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"using-r-arithmetic","dir":"Articles","previous_headings":"","what":"1. Using R arithmetic","title":"Matrix inversion by elementary row operations","text":"Now, elements diagonal zero","code":"(AI[2,] <- AI[2,] - 2*AI[1,]) # row 2 <- row 2 - 2 * row 1 ## [1] 0 -1 -6 -2 1 0 (AI[3,] <- AI[3,] + AI[2,]) # row 3 <- row 3 + row 2 ## [1] 0 0 -8 -2 1 1 (AI[2,] <- -1 * AI[2,]) # row 2 <- -1 * row 2 ## [1] 0 1 6 2 -1 0 (AI[3,] <- -(1/8) * AI[3,]) # row 3 <- -.25 * row 3 ## [1] 0.000 0.000 1.000 0.250 -0.125 -0.125 AI ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 2 3 1.00 0.000 0.000 ## [2,] 0 1 6 2.00 -1.000 0.000 ## [3,] 0 0 1 0.25 -0.125 -0.125 #--continue, making above diagonal == 0 AI[2,] <- AI[2,] - 6 * AI[3,] # row 2 <- row 2 - 6 * row 3 AI[1,] <- AI[1,] - 3 * AI[3,] # row 1 <- row 1 - 3 * row 3 AI[1,] <- AI[1,] - 2 * AI[2,] # row 1 <- row 1 - 2 * row 2 AI ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 0 -0.75 0.875 -1.125 ## [2,] 0 1 0 0.50 -0.250 0.750 ## [3,] 0 0 1 0.25 -0.125 -0.125 #-- last three cols are the inverse (AInv <- AI[,-(1:3)]) ## [,1] [,2] [,3] ## [1,] -0.75 0.875 -1.125 ## [2,] 0.50 -0.250 0.750 ## [3,] 0.25 -0.125 -0.125 #-- compare with inv() inv(A) ## [,1] [,2] [,3] ## [1,] -0.75 0.875 -1.125 ## [2,] 0.50 -0.250 0.750 ## [3,] 0.25 -0.125 -0.125"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"do-the-same-using-matlib-functions-rowadd-rowmult-and-rowswap","dir":"Articles","previous_headings":"","what":"2. Do the same, using matlib functions rowadd(), rowmult() and rowswap()","title":"Matrix inversion by elementary row operations","text":"","code":"AI <- cbind(A, diag(3)) AI <- rowadd(AI, 1, 2, -2) # row 2 <- row 2 - 2 * row 1 AI <- rowadd(AI, 2, 3, 1) # row 3 <- row 3 + row 2 AI <- rowmult(AI, 2, -1) # row 1 <- -1 * row 2 AI <- rowmult(AI, 3, -1/8) # row 3 <- -.25 * row 3 # show result so far AI ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 2 3 1.00 0.000 0.000 ## [2,] 0 1 6 2.00 -1.000 0.000 ## [3,] 0 0 1 0.25 -0.125 -0.125 #--continue, making above-diagonal == 0 AI <- rowadd(AI, 3, 2, -6) # row 2 <- row 2 - 6 * row 3 AI <- rowadd(AI, 2, 1, -2) # row 1 <- row 1 - 2 * row 2 AI <- rowadd(AI, 3, 1, -3) # row 1 <- row 1 - 3 * row 3 AI ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 0 -0.75 0.875 -1.125 ## [2,] 0 1 0 0.50 -0.250 0.750 ## [3,] 0 0 1 0.25 -0.125 -0.125"},{"path":"http://friendly.github.io/matlib/articles/inv-ex2.html","id":"using-echelon","dir":"Articles","previous_headings":"","what":"3. Using echelon()","title":"Matrix inversion by elementary row operations","text":"echelon() steps row row, returns result interesting see steps, using argument verbose=TRUE. many cases, informative see numbers printed fractions.","code":"echelon( cbind(A, diag(3))) ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 0 -0.75 0.875 -1.125 ## [2,] 0 1 0 0.50 -0.250 0.750 ## [3,] 0 0 1 0.25 -0.125 -0.125 echelon( cbind(A, diag(3)), verbose=TRUE, fractions=TRUE) ## ## Initial matrix: ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 2 3 1 0 0 ## [2,] 2 3 0 0 1 0 ## [3,] 0 1 -2 0 0 1 ## ## row: 1 ## ## exchange rows 1 and 2 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 2 3 0 0 1 0 ## [2,] 1 2 3 1 0 0 ## [3,] 0 1 -2 0 0 1 ## ## multiply row 1 by 1/2 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 3/2 0 0 1/2 0 ## [2,] 1 2 3 1 0 0 ## [3,] 0 1 -2 0 0 1 ## ## subtract row 1 from row 2 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 3/2 0 0 1/2 0 ## [2,] 0 1/2 3 1 -1/2 0 ## [3,] 0 1 -2 0 0 1 ## ## row: 2 ## ## exchange rows 2 and 3 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 3/2 0 0 1/2 0 ## [2,] 0 1 -2 0 0 1 ## [3,] 0 1/2 3 1 -1/2 0 ## ## multiply row 2 by 3/2 and subtract from row 1 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 3 0 1/2 -3/2 ## [2,] 0 1 -2 0 0 1 ## [3,] 0 1/2 3 1 -1/2 0 ## ## multiply row 2 by 1/2 and subtract from row 3 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 3 0 1/2 -3/2 ## [2,] 0 1 -2 0 0 1 ## [3,] 0 0 4 1 -1/2 -1/2 ## ## row: 3 ## ## multiply row 3 by 1/4 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 3 0 1/2 -3/2 ## [2,] 0 1 -2 0 0 1 ## [3,] 0 0 1 1/4 -1/8 -1/8 ## ## multiply row 3 by 3 and subtract from row 1 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 0 -3/4 7/8 -9/8 ## [2,] 0 1 -2 0 0 1 ## [3,] 0 0 1 1/4 -1/8 -1/8 ## ## multiply row 3 by 2 and add to row 2 ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 1 0 0 -3/4 7/8 -9/8 ## [2,] 0 1 0 1/2 -1/4 3/4 ## [3,] 0 0 1 1/4 -1/8 -1/8"},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"equations-in-two-unknowns","dir":"Articles","previous_headings":"","what":"Equations in two unknowns","title":"Solving Linear Equations","text":"equation two unknowns corresponds line 2D space. equations unique solution lines intersect point.","code":""},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"two-consistent-equations","dir":"Articles","previous_headings":"Equations in two unknowns","what":"Two consistent equations","title":"Solving Linear Equations","text":"Plot equations: Solve() convenience function shows solution comprehensible form:","code":"A <- matrix(c(1, 2, -1, 2), 2, 2) b <- c(2,1) showEqn(A, b) ## 1*x1 - 1*x2 = 2 ## 2*x1 + 2*x2 = 1 c( R(A), R(cbind(A,b)) ) # show ranks ## [1] 2 2 all.equal( R(A), R(cbind(A,b)) ) # consistent? ## [1] TRUE plotEqn(A,b) ## x[1] - 1*x[2] = 2 ## 2*x[1] + 2*x[2] = 1 Solve(A, b, fractions = TRUE) ## x1 = 5/4 ## x2 = -3/4"},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"three-consistent-equations","dir":"Articles","previous_headings":"Equations in two unknowns","what":"Three consistent equations","title":"Solving Linear Equations","text":"three () equations two unknowns, \\(r(\\mathbf{}) \\le 2\\), \\(r(\\mathbf{}) \\le \\min(m,n)\\). equations consistent \\(r(\\mathbf{}) = r(\\mathbf{| b})\\). means whatever linear relations exist among rows \\(\\mathbf{}\\) among elements \\(\\mathbf{b}\\). Geometrically, means three lines intersect point. Plot equations:","code":"A <- matrix(c(1,2,3, -1, 2, 1), 3, 2) b <- c(2,1,3) showEqn(A, b) ## 1*x1 - 1*x2 = 2 ## 2*x1 + 2*x2 = 1 ## 3*x1 + 1*x2 = 3 c( R(A), R(cbind(A,b)) ) # show ranks ## [1] 2 2 all.equal( R(A), R(cbind(A,b)) ) # consistent? ## [1] TRUE Solve(A, b, fractions=TRUE) # show solution ## x1 = 5/4 ## x2 = -3/4 ## 0 = 0 plotEqn(A,b) ## x[1] - 1*x[2] = 2 ## 2*x[1] + 2*x[2] = 1 ## 3*x[1] + x[2] = 3"},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"three-inconsistent-equations","dir":"Articles","previous_headings":"Equations in two unknowns","what":"Three inconsistent equations","title":"Solving Linear Equations","text":"Three equations two unknowns inconsistent \\(r(\\mathbf{}) < r(\\mathbf{| b})\\). can see result reducing \\(\\mathbf{} | \\mathbf{b}\\) echelon form, last row indicates inconsistency. Solve() shows explicitly: approximate solution sometimes available using generalized inverse. Plot equations. can see pair equations solution, three common, consistent solution.","code":"A <- matrix(c(1,2,3, -1, 2, 1), 3, 2) b <- c(2,1,6) showEqn(A, b) ## 1*x1 - 1*x2 = 2 ## 2*x1 + 2*x2 = 1 ## 3*x1 + 1*x2 = 6 c( R(A), R(cbind(A,b)) ) # show ranks ## [1] 2 3 all.equal( R(A), R(cbind(A,b)) ) # consistent? ## [1] \"Mean relative difference: 0.5\" echelon(A, b) ## [,1] [,2] [,3] ## [1,] 1 0 2.75 ## [2,] 0 1 -2.25 ## [3,] 0 0 -3.00 Solve(A, b, fractions=TRUE) ## x1 = 11/4 ## x2 = -9/4 ## 0 = -3 x <- MASS::ginv(A) %*% b x ## [,1] ## [1,] 2 ## [2,] -1 par(mar=c(4,4,0,0)+.1) plotEqn(A,b, xlim=c(-2, 4)) ## x[1] - 1*x[2] = 2 ## 2*x[1] + 2*x[2] = 1 ## 3*x[1] + x[2] = 6 points(x[1], x[2], pch=15)"},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"equations-in-three-unknowns","dir":"Articles","previous_headings":"","what":"Equations in three unknowns","title":"Solving Linear Equations","text":"equation three unknowns corresponds plane 3D space. equations unique solution planes intersect point.","code":""},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"three-consistent-equations-1","dir":"Articles","previous_headings":"Equations in three unknowns","what":"Three consistent equations","title":"Solving Linear Equations","text":"equations consistent? Solve \\(\\mathbf{x}\\). Another way see solution reduce \\(\\mathbf{| b}\\) echelon form. result \\(\\mathbf{| ^{-1}b}\\), solution last column. Plot . plotEqn3d uses rgl 3D graphics. rotate figure, ’ll see orientation three planes intersect solution point, \\(\\mathbf{x} = (2, 3, -1)\\)","code":"A <- matrix(c(2, 1, -1, -3, -1, 2, -2, 1, 2), 3, 3, byrow=TRUE) colnames(A) <- paste0('x', 1:3) b <- c(8, -11, -3) showEqn(A, b) ## 2*x1 + 1*x2 - 1*x3 = 8 ## -3*x1 - 1*x2 + 2*x3 = -11 ## -2*x1 + 1*x2 + 2*x3 = -3 c( R(A), R(cbind(A,b)) ) # show ranks ## [1] 3 3 all.equal( R(A), R(cbind(A,b)) ) # consistent? ## [1] TRUE solve(A, b) ## x1 x2 x3 ## 2 3 -1 solve(A) %*% b ## [,1] ## x1 2 ## x2 3 ## x3 -1 inv(A) %*% b ## [,1] ## [1,] 2 ## [2,] 3 ## [3,] -1 echelon(A, b) ## x1 x2 x3 ## [1,] 1 0 0 2 ## [2,] 0 1 0 3 ## [3,] 0 0 1 -1 echelon(A, b, verbose=TRUE, fractions=TRUE) ## ## Initial matrix: ## x1 x2 x3 ## [1,] 2 1 -1 8 ## [2,] -3 -1 2 -11 ## [3,] -2 1 2 -3 ## ## row: 1 ## ## exchange rows 1 and 2 ## x1 x2 x3 ## [1,] -3 -1 2 -11 ## [2,] 2 1 -1 8 ## [3,] -2 1 2 -3 ## ## multiply row 1 by -1/3 ## x1 x2 x3 ## [1,] 1 1/3 -2/3 11/3 ## [2,] 2 1 -1 8 ## [3,] -2 1 2 -3 ## ## multiply row 1 by 2 and subtract from row 2 ## x1 x2 x3 ## [1,] 1 1/3 -2/3 11/3 ## [2,] 0 1/3 1/3 2/3 ## [3,] -2 1 2 -3 ## ## multiply row 1 by 2 and add to row 3 ## x1 x2 x3 ## [1,] 1 1/3 -2/3 11/3 ## [2,] 0 1/3 1/3 2/3 ## [3,] 0 5/3 2/3 13/3 ## ## row: 2 ## ## exchange rows 2 and 3 ## x1 x2 x3 ## [1,] 1 1/3 -2/3 11/3 ## [2,] 0 5/3 2/3 13/3 ## [3,] 0 1/3 1/3 2/3 ## ## multiply row 2 by 3/5 ## x1 x2 x3 ## [1,] 1 1/3 -2/3 11/3 ## [2,] 0 1 2/5 13/5 ## [3,] 0 1/3 1/3 2/3 ## ## multiply row 2 by 1/3 and subtract from row 1 ## x1 x2 x3 ## [1,] 1 0 -4/5 14/5 ## [2,] 0 1 2/5 13/5 ## [3,] 0 1/3 1/3 2/3 ## ## multiply row 2 by 1/3 and subtract from row 3 ## x1 x2 x3 ## [1,] 1 0 -4/5 14/5 ## [2,] 0 1 2/5 13/5 ## [3,] 0 0 1/5 -1/5 ## ## row: 3 ## ## multiply row 3 by 5 ## x1 x2 x3 ## [1,] 1 0 -4/5 14/5 ## [2,] 0 1 2/5 13/5 ## [3,] 0 0 1 -1 ## ## multiply row 3 by 4/5 and add to row 1 ## x1 x2 x3 ## [1,] 1 0 0 2 ## [2,] 0 1 2/5 13/5 ## [3,] 0 0 1 -1 ## ## multiply row 3 by 2/5 and subtract from row 2 ## x1 x2 x3 ## [1,] 1 0 0 2 ## [2,] 0 1 0 3 ## [3,] 0 0 1 -1 plotEqn3d(A,b, xlim=c(0,4), ylim=c(0,4))"},{"path":"http://friendly.github.io/matlib/articles/linear-equations.html","id":"three-inconsistent-equations-1","dir":"Articles","previous_headings":"Equations in three unknowns","what":"Three inconsistent equations","title":"Solving Linear Equations","text":"equations consistent? .","code":"A <- matrix(c(1, 3, 1, 1, -2, -2, 2, 1, -1), 3, 3, byrow=TRUE) colnames(A) <- paste0('x', 1:3) b <- c(2, 3, 6) showEqn(A, b) ## 1*x1 + 3*x2 + 1*x3 = 2 ## 1*x1 - 2*x2 - 2*x3 = 3 ## 2*x1 + 1*x2 - 1*x3 = 6 c( R(A), R(cbind(A,b)) ) # show ranks ## [1] 2 3 all.equal( R(A), R(cbind(A,b)) ) # consistent? ## [1] \"Mean relative difference: 0.5\""},{"path":"http://friendly.github.io/matlib/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Michael Friendly. Author, maintainer. John Fox. Author. Phil Chalmers. Author. Georges Monette. Contributor. Gaston Sanchez. Contributor.","code":""},{"path":"http://friendly.github.io/matlib/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Friendly M, Fox J, Chalmers P (2024). matlib: Matrix Functions Teaching Learning Linear Algebra Multivariate Statistics. https://github.com/friendly/matlib, http://friendly.github.io/matlib/.","code":"@Manual{, title = {matlib: Matrix Functions for Teaching and Learning Linear Algebra and Multivariate Statistics}, author = {Michael Friendly and John Fox and Phil Chalmers}, year = {2024}, note = {https://github.com/friendly/matlib, http://friendly.github.io/matlib/}, }"},{"path":"http://friendly.github.io/matlib/index.html","id":"matlib-","dir":"","previous_headings":"","what":"Matrix Functions for Teaching and Learning Linear Algebra and\n Multivariate Statistics","title":"Matrix Functions for Teaching and Learning Linear Algebra and\n Multivariate Statistics","text":"Matrix Functions Teaching Learning Linear Algebra Multivariate Statistics, http://friendly.github.io/matlib/ Version 0.9.9 functions originally designed tutorial purposes teaching & learning matrix algebra ideas using R. cases, functions provided concepts computations available elsewhere R, name obvious, e.g., R() rank matrix, tr() matrix trace. cases, provide cover functions show demonstrate algorithm detail, sometimes providing verbose = argument print details computations, e.g., Det() matrix determinant, Inverse() matrix inverse, using gaussianElimination() show steps. addition, collection functions provided drawing vector diagrams 2D 3D, illustrating various concepts linear algebra concretely available . example, showEqn(, b) shows matrix equations Ax = b text LaTeX form, plotEqn(, b) plotEqn3d(, b) plots equations 2D 3D space. matrix2latex() symbolicMatrix() facilitate writing matrix equations LaTeX vectors(), vectors3d() plot geometric vector diagrams 2D 3D, functions draw angles arcs. regvec3d() calculates plot vectors representing bivariate regression model, lm(y ~ x1 + x2)","code":""},{"path":"http://friendly.github.io/matlib/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Matrix Functions for Teaching and Learning Linear Algebra and\n Multivariate Statistics","text":"Get released version CRAN: development version R-universe: development version can also installed R library directly repo via: functions draw 3D graphs use rgl package. macOS, rgl requires XQuartz installed. installing XQuartz, ’s necessary either log back macOS account reboot Mac.","code":"install.packages(\"matlib\") install.packages('matlib', repos = c('https://friendly.r-universe.dev', 'https://cloud.r-project.org')) if (!require(remotes)) install.packages(\"remotes\") remotes::install_github(\"friendly/matlib\", build_vignettes = TRUE)"},{"path":"http://friendly.github.io/matlib/index.html","id":"topics","dir":"","previous_headings":"","what":"Topics","title":"Matrix Functions for Teaching and Learning Linear Algebra and\n Multivariate Statistics","text":"functions package grouped following topics Convenience functions: tr() - trace matrix R() - rank matrix J() - constant vector, matrix array len() - Euclidean length vector columns matrix vec() - vectorize matrix Proj(y, X) - projection vector y columns matrix X mpower(, p) - matrix powers square symmetric matrix xprod(...) - vector cross-product Determinants: functions calculating determinants cofactor expansion minor() - Minor [,j] cofactor() - Cofactor [,j] rowMinors() - Row minors [,] rowCofactors() - Row cofactors [,] Det() - Determinants elimination eigenvalues Elementary row operations: functions solving linear equations “manually” steps used row echelon form Gaussian elimination rowadd() - Add multiples rows rows rowmult() - Multiply rows constants rowswap() - Interchange two rows matrix Linear equations: functions illustrate linear equations form Ax = b showEqn(, b) - show matrices (, b) linear equations plotEqn(, b), plotEqn3d(, b) - plot matrices (, b) linear equations Gaussian elimination: functions illustrating Gaussian elimination solving systems linear equations form Ax = b. functions provide verbose=TRUE argument show intermediate steps fractions=TRUE argument show results using MASS::fractions(). gaussianElimination(, B) - reduces (,B) (,−1B) Inverse(X), inv() - uses gaussianElimination find inverse X, X−1 echelon(X) - uses gaussianElimination find reduced echelon form X Ginv(X) - uses gaussianElimination find generalized inverse X LU(X) - LU decomposition matrix X cholesky(X) - calculates Cholesky square root matrix swp() - matrix sweep operator Eigenvalues: functions illustrate algorithms calculating eigenvalues eigenvectors related matrix decompositions generalizations. Eigen() - eigenvalues eigenvectors SVD() - singular value decomposition, $mathbf{X = U D V}$ powerMethod() - find dominant eigenvector using power method showEig() - draw eigenvectors 2D scatterplot dataEllipse MoorePenrose() - illustrates Moore-Penrose inverse can calculated using SVD() Vector diagrams: functions drawing vector diagrams 2D 3D arrows3d() - draw nice 3D arrows corner(), arc() - draw corner arc showing angle two vectors 2D/3D pointOnLine() - position point along line vectors(), vectors3d() - plot geometric vector diagrams 2D/3D regvec3d() - calculate plot vectors representing bivariate regression model, lm(y ~ x1 + x2) mean-deviation form. Matrix equations matrix2latex(): Convert matrix LaTeX equation symbolicMatrix(): Create symbolic matrix LaTeX","code":""},{"path":"http://friendly.github.io/matlib/index.html","id":"vignettes-and-presentations","dir":"","previous_headings":"Topics","what":"Vignettes and presentations","title":"Matrix Functions for Teaching and Learning Linear Algebra and\n Multivariate Statistics","text":"small collection vignettes now available. Use browseVignettes(\"matlib\") explore . See also: Fox & Friendly, Visualizing Simultaneous Linear Equations, Geometric Vectors, Least-Squares Regression matlib Package R, June 2016, useR! Conference, Stanford. Ivan Savov, Linear algebra explained four pages","code":""},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculate the Adjoint of a matrix — adjoint","title":"Calculate the Adjoint of a matrix — adjoint","text":"function calculates adjoint square matrix, defined transposed matrix cofactors elements.","code":""},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculate the Adjoint of a matrix — adjoint","text":"","code":"adjoint(A)"},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculate the Adjoint of a matrix — adjoint","text":"square matrix","code":""},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculate the Adjoint of a matrix — adjoint","text":"matrix size ","code":""},{"path":[]},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"Calculate the Adjoint of a matrix — adjoint","text":"Michael Friendly","code":""},{"path":"http://friendly.github.io/matlib/reference/adjoint.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Calculate the Adjoint of a matrix — adjoint","text":"","code":"A <- J(3, 3) + 2*diag(3) adjoint(A) #> [,1] [,2] [,3] #> [1,] 8 -2 -2 #> [2,] -2 8 -2 #> [3,] -2 -2 8"},{"path":"http://friendly.github.io/matlib/reference/angle.html","id":null,"dir":"Reference","previous_headings":"","what":"Angle between two vectors — angle","title":"Angle between two vectors — angle","text":"angle calculates angle two vectors.","code":""},{"path":"http://friendly.github.io/matlib/reference/angle.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Angle between two vectors — angle","text":"","code":"angle(x, y, degree = TRUE)"},{"path":"http://friendly.github.io/matlib/reference/angle.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Angle between two vectors — angle","text":"x numeric vector y numeric vector degree logical; angle computed degrees? FALSE result returned radians","code":""},{"path":"http://friendly.github.io/matlib/reference/angle.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Angle between two vectors — angle","text":"scalar containing angle vectors","code":""},{"path":[]},{"path":"http://friendly.github.io/matlib/reference/angle.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Angle between two vectors — angle","text":"","code":"x <- c(2,1) y <- c(1,1) angle(x, y) # degrees #> [,1] #> [1,] 18.43495 angle(x, y, degree = FALSE) # radians #> [,1] #> [1,] 0.3217506 # visually xlim <- c(0,2.5) ylim <- c(0,2) # proper geometry requires asp=1 plot( xlim, ylim, type=\"n\", xlab=\"X\", ylab=\"Y\", asp=1, main = expression(theta == 18.4)) abline(v=0, h=0, col=\"gray\") vectors(rbind(x,y), col=c(\"red\", \"blue\"), cex.lab=c(2, 2)) text(.5, .37, expression(theta)) #### x <- c(-2,1) y <- c(1,1) angle(x, y) # degrees #> [,1] #> [1,] 108.4349 angle(x, y, degree = FALSE) # radians #> [,1] #> [1,] 1.892547 # visually xlim <- c(-2,1.5) ylim <- c(0,2) # proper geometry requires asp=1 plot( xlim, ylim, type=\"n\", xlab=\"X\", ylab=\"Y\", asp=1, main = expression(theta == 108.4)) abline(v=0, h=0, col=\"gray\") vectors(rbind(x,y), col=c(\"red\", \"blue\"), cex.lab=c(2, 2)) text(0, .4, expression(theta), cex=1.5)"},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":null,"dir":"Reference","previous_headings":"","what":"Draw an arc showing the angle between vectors — arc","title":"Draw an arc showing the angle between vectors — arc","text":"utility function drawing vector diagrams. Draws circular arc show angle two vectors 2D 3D.","code":""},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Draw an arc showing the angle between vectors — arc","text":"","code":"arc(p1, p2, p3, d = 0.1, absolute = TRUE, ...)"},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Draw an arc showing the angle between vectors — arc","text":"p1 Starting point first vector p2 End point first vector, also start second vector p3 End point second vector d distance p2 along vector drawing corner absolute logical; TRUE, d taken absolute distance along vectors; otherwise calculated relative distance, .e., fraction length vectors. ... Arguments passed link[graphics]{lines} link[rgl]{lines3d}","code":""},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Draw an arc showing the angle between vectors — arc","text":"none","code":""},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Draw an arc showing the angle between vectors — arc","text":"implementation, two vectors specified three points, p1, p2, p3, meaning line p1 p2, another line p2 p3.","code":""},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"references","dir":"Reference","previous_headings":"","what":"References","title":"Draw an arc showing the angle between vectors — arc","text":"https://math.stackexchange.com/questions/1507248/find-arc--two-tips--vectors--3d","code":""},{"path":[]},{"path":"http://friendly.github.io/matlib/reference/arc.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Draw an arc showing the angle between vectors — arc","text":"3D plot","code":"library(rgl) #> Warning: package 'rgl' was built under R version 4.3.3 #> #> Attaching package: 'rgl' #> The following object is masked from 'package:matlib': #> #> GramSchmidt vec <- rbind(diag(3), c(1,1,1)) rownames(vec) <- c(\"X\", \"Y\", \"Z\", \"J\") open3d() aspect3d(\"iso\") vectors3d(vec, col=c(rep(\"black\",3), \"red\"), lwd=2) # draw the XZ plane, whose equation is Y=0 planes3d(0, 0, 1, 0, col=\"gray\", alpha=0.2) # show projections of the unit vector J segments3d(rbind( c(1,1,1), c(1, 1, 0))) segments3d(rbind( c(0,0,0), c(1, 1, 0))) segments3d(rbind( c(1,0,0), c(1, 1, 0))) segments3d(rbind( c(0,1,0), c(1, 1, 0))) segments3d(rbind( c(1,1,1), c(1, 0, 0))) # show some orthogonal vectors p1 <- c(0,0,0) p2 <- c(1,1,0) p3 <- c(1,1,1) p4 <- c(1,0,0) # show some angles arc(p1, p2, p3, d=.2) arc(p4, p1, p2, d=.2) arc(p3, p1, p2, d=.2) 3D plot {\"x\":{\"material\":{\"color\":\"#000000\",\"alpha\":1,\"lit\":true,\"ambient\":\"#000000\",\"specular\":\"#FFFFFF\",\"emission\":\"#000000\",\"shininess\":50,\"smooth\":true,\"front\":\"filled\",\"back\":\"filled\",\"size\":3,\"lwd\":1,\"fog\":true,\"point_antialias\":false,\"line_antialias\":false,\"texture\":null,\"textype\":\"rgb\",\"texmode\":\"modulate\",\"texmipmap\":false,\"texminfilter\":\"linear\",\"texmagfilter\":\"linear\",\"texenvmap\":false,\"depth_mask\":true,\"depth_test\":\"less\",\"isTransparent\":false,\"polygon_offset\":[0,0],\"margin\":\"\",\"floating\":false,\"tag\":\"\",\"blend\":[\"src_alpha\",\"one_minus_src_alpha\"]},\"rootSubscene\":1,\"objects\":{\"7\":{\"id\":7,\"type\":\"lines\",\"material\":{\"lit\":false,\"lwd\":2},\"vertices\":\"0\",\"colors\":\"1\",\"centers\":\"2\",\"ignoreExtent\":false,\"flags\":41024},\"8\":{\"id\":8,\"type\":\"triangles\",\"material\":{\"lwd\":2},\"vertices\":\"3\",\"colors\":\"5\",\"centers\":\"6\",\"normals\":\"4\",\"ignoreExtent\":false,\"flags\":32771},\"9\":{\"id\":9,\"type\":\"triangles\",\"material\":{\"lwd\":2},\"vertices\":\"7\",\"colors\":\"9\",\"centers\":\"10\",\"normals\":\"8\",\"ignoreExtent\":false,\"flags\":32771},\"10\":{\"id\":10,\"type\":\"triangles\",\"material\":{\"lwd\":2},\"vertices\":\"11\",\"colors\":\"13\",\"centers\":\"14\",\"normals\":\"12\",\"ignoreExtent\":false,\"flags\":32771},\"11\":{\"id\":11,\"type\":\"triangles\",\"material\":{\"lwd\":2},\"vertices\":\"15\",\"colors\":\"17\",\"centers\":\"18\",\"normals\":\"16\",\"ignoreExtent\":false,\"flags\":32771},\"12\":{\"id\":12,\"type\":\"text\",\"material\":{\"lit\":false,\"lwd\":2},\"vertices\":\"19\",\"colors\":\"20\",\"texts\":[[\"\"],[\"\"],[\"\"],[\"\"],[\"X\"],[\"Y\"],[\"Z\"],[\"J\"]],\"cex\":[[1.2]],\"adj\":[[0.5,0.5,0.5]],\"centers\":\"21\",\"family\":[[\"sans\"]],\"font\":[[1]],\"ignoreExtent\":false,\"flags\":33808},\"13\":{\"id\":13,\"type\":\"planes\",\"material\":{\"alpha\":0.2000000029802322,\"isTransparent\":true},\"vertices\":\"22\",\"colors\":\"24\",\"offsets\":[[0]],\"centers\":\"25\",\"normals\":\"23\",\"ignoreExtent\":true,\"flags\":32803},\"14\":{\"id\":14,\"type\":\"lines\",\"material\":{\"lit\":false},\"vertices\":\"26\",\"colors\":\"27\",\"centers\":\"28\",\"ignoreExtent\":false,\"flags\":32832},\"15\":{\"id\":15,\"type\":\"lines\",\"material\":{\"lit\":false},\"vertices\":\"29\",\"colors\":\"30\",\"centers\":\"31\",\"ignoreExtent\":false,\"flags\":32832},\"16\":{\"id\":16,\"type\":\"lines\",\"material\":{\"lit\":false},\"vertices\":\"32\",\"colors\":\"33\",\"centers\":\"34\",\"ignoreExtent\":false,\"flags\":32832},\"17\":{\"id\":17,\"type\":\"lines\",\"material\":{\"lit\":false},\"vertices\":\"35\",\"colors\":\"36\",\"centers\":\"37\",\"ignoreExtent\":false,\"flags\":32832},\"18\":{\"id\":18,\"type\":\"lines\",\"material\":{\"lit\":false},\"vertices\":\"38\",\"colors\":\"39\",\"centers\":\"40\",\"ignoreExtent\":false,\"flags\":32832},\"19\":{\"id\":19,\"type\":\"linestrip\",\"material\":{\"lit\":false},\"vertices\":\"41\",\"colors\":\"42\",\"centers\":\"43\",\"ignoreExtent\":false,\"flags\":32832},\"20\":{\"id\":20,\"type\":\"linestrip\",\"material\":{\"lit\":false},\"vertices\":\"44\",\"colors\":\"45\",\"centers\":\"46\",\"ignoreExtent\":false,\"flags\":32832},\"21\":{\"id\":21,\"type\":\"linestrip\",\"material\":{\"lit\":false},\"vertices\":\"47\",\"colors\":\"48\",\"centers\":\"49\",\"ignoreExtent\":false,\"flags\":32832},\"5\":{\"id\":5,\"type\":\"light\",\"vertices\":[[0,0,1]],\"colors\":[[1,1,1,1],[1,1,1,1],[1,1,1,1]],\"viewpoint\":true,\"finite\":false},\"4\":{\"id\":4,\"type\":\"background\",\"material\":{},\"colors\":\"50\",\"centers\":\"51\",\"sphere\":false,\"fogtype\":\"none\",\"fogscale\":1,\"flags\":32768},\"6\":{\"id\":6,\"type\":\"background\",\"material\":{\"lit\":false,\"back\":\"lines\"},\"colors\":\"52\",\"centers\":\"53\",\"sphere\":false,\"fogtype\":\"none\",\"fogscale\":1,\"flags\":32768},\"1\":{\"id\":1,\"type\":\"subscene\",\"par3d\":{\"antialias\":8,\"FOV\":30,\"ignoreExtent\":false,\"listeners\":1,\"mouseMode\":{\"none\":\"none\",\"left\":\"trackball\",\"right\":\"zoom\",\"middle\":\"fov\",\"wheel\":\"pull\"},\"observer\":[0,0,3.735036373138428],\"modelMatrix\":[[1,0,0,-0.5417932868003845],[0,0.3420201539993286,0.9396926164627075,-0.6947333812713623],[0,-0.9396926164627075,0.3420201539993286,-3.411468982696533],[0,0,0,1]],\"projMatrix\":[[3.732050895690918,0,0,0],[0,3.732050895690918,0,0],[0,0,-3.863703727722168,-13.46437454223633],[0,0,-1,0]],\"skipRedraw\":false,\"userMatrix\":[[1,0,0,0],[0,0.3420201433256682,0.9396926207859085,0],[0,-0.9396926207859085,0.3420201433256682,0],[0,0,0,1]],\"userProjection\":[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],\"scale\":[1,1,1],\"viewport\":{\"x\":0,\"y\":0,\"width\":1,\"height\":1},\"zoom\":1,\"bbox\":[-0.01641346327960491,1.100000023841858,-0.01666666753590107,1.100000023841858,-0.01566154323518276,1.100000023841858],\"windowRect\":[0,0,256,256],\"family\":\"sans\",\"font\":1,\"cex\":1,\"useFreeType\":false,\"fontname\":\"NULL\",\"maxClipPlanes\":2147483647,\"glVersion\":\"NA\",\"activeSubscene\":0},\"embeddings\":{\"viewport\":\"replace\",\"projection\":\"replace\",\"model\":\"replace\",\"mouse\":\"replace\"},\"objects\":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,5],\"subscenes\":[],\"flags\":42355}},\"crosstalk\":{\"key\":[],\"group\":[],\"id\":[],\"options\":[]},\"width\":700,\"height\":432.6328800988875,\"buffer\":{\"accessors\":[{\"bufferView\":0,\"componentType\":5121,\"count\":8,\"type\":\"VEC3\"},{\"bufferView\":1,\"componentType\":5121,\"count\":8,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":2,\"componentType\":5126,\"count\":4,\"type\":\"VEC3\"},{\"bufferView\":3,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":4,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":5,\"componentType\":5121,\"count\":54,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":6,\"componentType\":5126,\"count\":18,\"type\":\"VEC3\"},{\"bufferView\":7,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":8,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":9,\"componentType\":5121,\"count\":54,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":10,\"componentType\":5126,\"count\":18,\"type\":\"VEC3\"},{\"bufferView\":11,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":12,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":13,\"componentType\":5121,\"count\":54,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":14,\"componentType\":5126,\"count\":18,\"type\":\"VEC3\"},{\"bufferView\":15,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":16,\"componentType\":5126,\"count\":54,\"type\":\"VEC3\"},{\"bufferView\":17,\"componentType\":5121,\"count\":54,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":18,\"componentType\":5126,\"count\":18,\"type\":\"VEC3\"},{\"bufferView\":19,\"componentType\":5126,\"count\":8,\"type\":\"VEC3\"},{\"bufferView\":20,\"componentType\":5121,\"count\":4,\"type\":\"VEC4\",\"normalized\":true},{\"bufferView\":21,\"componentType\":5126,\"count\":8,\"type\":\"VEC3\"},{\"bufferView\":22,\"componentType\":5126,\"count\":3,\"type\":\"VEC3\"},{\"bufferView\":23,\"componentType\":5121,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":24,\"componentType\":5126,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":25,\"componentType\":5126,\"count\":4,\"type\":\"VEC3\"},{\"bufferView\":26,\"componentType\":5121,\"count\":2,\"type\":\"VEC3\"},{\"bufferView\":27,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":28,\"componentType\":5126,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":29,\"componentType\":5121,\"count\":2,\"type\":\"VEC3\"},{\"bufferView\":30,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":31,\"componentType\":5126,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":32,\"componentType\":5121,\"count\":2,\"type\":\"VEC3\"},{\"bufferView\":33,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":34,\"componentType\":5126,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":35,\"componentType\":5121,\"count\":2,\"type\":\"VEC3\"},{\"bufferView\":36,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":37,\"componentType\":5126,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":38,\"componentType\":5121,\"count\":2,\"type\":\"VEC3\"},{\"bufferView\":39,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":40,\"componentType\":5126,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":41,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":42,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":43,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":44,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":45,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":46,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":47,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":48,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":49,\"componentType\":5126,\"count\":10,\"type\":\"VEC3\"},{\"bufferView\":50,\"componentType\":5126,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":51,\"componentType\":5121,\"count\":1,\"type\":\"VEC3\"},{\"bufferView\":52,\"componentType\":5121,\"count\":1,\"type\":\"VEC4\"},{\"bufferView\":53,\"componentType\":5121,\"count\":1,\"type\":\"VEC3\"}],\"bufferViews\":[{\"buffer\":0,\"byteLength\":24,\"byteOffset\":0},{\"buffer\":0,\"byteLength\":32,\"byteOffset\":24},{\"buffer\":0,\"byteLength\":48,\"byteOffset\":56},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":104},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":752},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":1400},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":1616},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":1832},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":2480},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":3128},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":3344},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":3560},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":4208},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":4856},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":5072},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":5288},{\"buffer\":0,\"byteLength\":648,\"byteOffset\":5936},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":6584},{\"buffer\":0,\"byteLength\":216,\"byteOffset\":6800},{\"buffer\":0,\"byteLength\":96,\"byteOffset\":7016},{\"buffer\":0,\"byteLength\":16,\"byteOffset\":7112},{\"buffer\":0,\"byteLength\":96,\"byteOffset\":7128},{\"buffer\":0,\"byteLength\":36,\"byteOffset\":7224},{\"buffer\":0,\"byteLength\":3,\"byteOffset\":7260},{\"buffer\":0,\"byteLength\":16,\"byteOffset\":7264},{\"buffer\":0,\"byteLength\":48,\"byteOffset\":7280},{\"buffer\":0,\"byteLength\":6,\"byteOffset\":7328},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7334},{\"buffer\":0,\"byteLength\":12,\"byteOffset\":7340},{\"buffer\":0,\"byteLength\":6,\"byteOffset\":7352},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7358},{\"buffer\":0,\"byteLength\":12,\"byteOffset\":7364},{\"buffer\":0,\"byteLength\":6,\"byteOffset\":7376},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7382},{\"buffer\":0,\"byteLength\":12,\"byteOffset\":7388},{\"buffer\":0,\"byteLength\":6,\"byteOffset\":7400},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7406},{\"buffer\":0,\"byteLength\":12,\"byteOffset\":7412},{\"buffer\":0,\"byteLength\":6,\"byteOffset\":7424},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7430},{\"buffer\":0,\"byteLength\":12,\"byteOffset\":7436},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":7448},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7568},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":7572},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":7692},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":7812},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":7816},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":7936},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":8056},{\"buffer\":0,\"byteLength\":120,\"byteOffset\":8060},{\"buffer\":0,\"byteLength\":16,\"byteOffset\":8180},{\"buffer\":0,\"byteLength\":3,\"byteOffset\":8196},{\"buffer\":0,\"byteLength\":4,\"byteOffset\":8199},{\"buffer\":0,\"byteLength\":3,\"byteOffset\":8203}],\"buffers\":[{\"byteLength\":8206,\"bytes\":\"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\\nF3twPwAAAAAAAAAAF3twP4mIiDwchi88F3twP2MuUTwAAAAAF3twPwAAAAAchi88F3twP2Mu\\nUTyHdYY8F3twP42rPTsAAAAAF3twPwAAAACHdYY8F3twP42rPTuQe2w8F3twP4mICLwAAAAA\\nF3twPwAAAACQe2w8F3twP4mICLziybo7F3twP6NMgLwAAAAAF3twPwAAAADiybo7F3twP6NM\\ngLziybq7F3twP6NMgLwAAAAAF3twPwAAAADiybq7F3twP6NMgLyQe2y8F3twP4mICLwAAAAA\\nF3twPwAAAACQe2y8F3twP4mICLyHdYa8F3twP42rPTsAAAAAF3twPwAAAACHdYa8F3twP42r\\nPTschi+8F3twP2MuUTwAAAAAF3twPwAAAAAchi+8F3twP2MuUTyamZaiF3twP4mIiDwAAAAA\\nAACAPwAAAAAAAAAAF3twP4mIiDwchi88F3twP2MuUTwAAAAAAACAPwAAAAAchi88F3twP2Mu\\nUTyHdYY8F3twP42rPTsAAAAAAACAPwAAAACHdYY8F3twP42rPTuQe2w8F3twP4mICLwAAAAA\\nAACAPwAAAACQe2w8F3twP4mICLziybo7F3twP6NMgLwAAAAAAACAPwAAAADiybo7F3twP6NM\\ngLziybq7F3twP6NMgLwAAAAAAACAPwAAAADiybq7F3twP6NMgLyQe2y8F3twP4mICLwAAAAA\\nAACAPwAAAACQe2y8F3twP4mICLyHdYa8F3twP42rPTsAAAAAAACAPwAAAACHdYa8F3twP42r\\nPTschi+8F3twP2MuUTwAAAAAAACAPwAAAAAchi+8F3twP2MuUTyamZaiF3twP4mIiDwAAAAA\\n//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAA\\nAAAAAAAA//9/PwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAA\\n//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAAAAAAAAAA//9/PwAA\\nAAAAAAAA//9/PwAAAAAAAAAA//9/PwAAAIAAAAAA//9/PwAAAIAAAAAA//9/PwAAAIAAAAAA\\n//9/PwAAAIAAAAAA//9/PwAAAIAAAAAA//9/PwAAAIAAAACA//9/PwAAAAAAAACA//9/PwAA\\n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\\ngD6ep1Y/q9z3vskRgD6tGHQ/yCksPsoRgD6tGHQ/yCksPsoRgD6tGHQ/yCksPsoRgD6WUh8/\\nkN89P8oRgD6WUh8/kN89P8oRgD6WUh8/kN89P8oRgD4AAAAAqtx3P8kRgD4AAAAAqtx3P8kR\\ngD4AAAAAqtx3P8kRgD6WUh+/kN89P8oRgD6WUh+/kN89P8oRgD6WUh+/kN89P8oRgD6tGHS/\\nyCksPsoRgD6tGHS/yCksPsoRgD6tGHS/yCksPsoRgD6ep1a/q9z3vskRgD6ep1a/q9z3vskR\\ngD6ep1a/q9z3vskRgD4wjKm+/+lov8kRgD4wjKm+/+lov8kRgD4wjKm+/+lov8kRgD4AAAD/\\nAAAA/wAAAP//AAD/AAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAA\\nAP//AAD/AAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/\\nAAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/AAAA/wAA\\nAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/AAAA/wAAAP8mCGo7\\n0r8gvBd7cD+5JRQ82hCruxd7cD+Kdyg8ZqTtOhd7cD8A69s7RgsDPBd7cD8AAAAA2hArPBd7\\ncD8A69u7RgsDPBd7cD+Kdyi8ZqTtOhd7cD+5JRS82hCruxd7cD8mCGq70r8gvBd7cD8mCGo7\\n0r8gvGandT+5JRQ82hCru2andT+Kdyg8ZqTtOmandT8A69s7RgsDPGandT8AAAAA2hArPGan\\ndT8A69u7RgsDPGandT+Kdyi8ZqTtOmandT+5JRS82hCru2andT8mCGq70r8gvGandT89Cnc/\\nPQp3Pz0Kdz9rI3Y/n5N0P69nej8lg3g/zZFzP8YJeT89Cnc/PQp3Pz0Kdz8lg3g/zZFzP8YJ\\neT+EMno/si90P4O8dj89Cnc/PQp3Pz0Kdz+EMno/si90P4O8dj+vZ3o/ayN2P5+TdD89Cnc/\\nPQp3Pz0Kdz+vZ3o/ayN2P5+TdD/GCXk/JYN4P82Rcz89Cnc/PQp3Pz0Kdz/GCXk/JYN4P82R\\ncz+DvHY/hDJ6P7IvdD89Cnc/PQp3Pz0Kdz+DvHY/hDJ6P7IvdD+fk3Q/r2d6P2sjdj89Cnc/\\nPQp3Pz0Kdz+fk3Q/r2d6P2sjdj/NkXM/xgl5PyWDeD89Cnc/PQp3Pz0Kdz/NkXM/xgl5PyWD\\neD+yL3Q/g7x2P4Qyej89Cnc/PQp3Pz0Kdz+yL3Q/g7x2P4Qyej9rI3Y/n5N0P69nej8AAIA/\\nAACAPwAAgD9rI3Y/n5N0P69nej8lg3g/zZFzP8YJeT8AAIA/AACAPwAAgD8lg3g/zZFzP8YJ\\neT+EMno/si90P4O8dj8AAIA/AACAPwAAgD+EMno/si90P4O8dj+vZ3o/ayN2P5+TdD8AAIA/\\nAACAPwAAgD+vZ3o/ayN2P5+TdD/GCXk/JYN4P82Rcz8AAIA/AACAPwAAgD/GCXk/JYN4P82R\\ncz+DvHY/hDJ6P7IvdD8AAIA/AACAPwAAgD+DvHY/hDJ6P7IvdD+fk3Q/r2d6P2sjdj8AAIA/\\nAACAPwAAgD+fk3Q/r2d6P2sjdj/NkXM/xgl5PyWDeD8AAIA/AACAPwAAgD/NkXM/xgl5PyWD\\neD+yL3Q/g7x2P4Qyej8AAIA/AACAPwAAgD+yL3Q/g7x2P4Qyej9rI3Y/n5N0P69nej9fzRM/\\nUc0TP/3MEz9fzRM/Uc0TP/3MEz9fzRM/Uc0TP/3MEz/+zBM/XM0TP1fNEz/+zBM/XM0TP1fN\\nEz/+zBM/XM0TP1fNEz/+zBM/Xs0TP1XNEz/+zBM/Xs0TP1XNEz/+zBM/Xs0TP1XNEz/9zBM/\\nX80TP1HNEz/9zBM/X80TP1HNEz/9zBM/X80TP1HNEz9XzRM//swTP1zNEz9XzRM//swTP1zN\\nEz9XzRM//swTP1zNEz9VzRM//swTP17NEz9VzRM//swTP17NEz9VzRM//swTP17NEz9RzRM/\\n/cwTP1/NEz9RzRM//cwTP1/NEz9RzRM//cwTP1/NEz9czRM/V80TP/7MEz9czRM/V80TP/7M\\nEz9czRM/V80TP/7MEz9ezRM/Vc0TP/7MEz9ezRM/Vc0TP/7MEz9ezRM/Vc0TP/7MEz9Lb1o+\\nU3ISv9S/Sj9Lb1o+U3ISv9S/Sj9Lb1o+U3ISv9S/Sj/gEjQ/FYMevxmzsj7gEjQ/FYMevxmz\\nsj7gEjQ/FYMevxmzsj4xlG4/pjeevh08Qr4xlG4/pjeevh08Qr4xlG4/pjeevh08Qr7Uv0o/\\nS29aPlNyEr/Uv0o/S29aPlNyEr/Uv0o/S29aPlNyEr8Zs7I+4BI0PxWDHr8Zs7I+4BI0PxWD\\nHr8Zs7I+4BI0PxWDHr8dPEK+MZRuP6Y3nr4dPEK+MZRuP6Y3nr4dPEK+MZRuP6Y3nr5TchK/\\n1L9KP0tvWj5TchK/1L9KP0tvWj5TchK/1L9KP0tvWj4Vgx6/GbOyPuASND8Vgx6/GbOyPuAS\\nND8Vgx6/GbOyPuASND+mN56+HTxCvjGUbj+mN56+HTxCvjGUbj+mN56+HTxCvjGUbj8AAAD/\\nAAAA/wAAAP//AAD/AAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAA\\nAP//AAD/AAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/\\nAAAA/wAAAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/AAAA/wAA\\nAP8AAAD//wAA/wAAAP8AAAD/AAAA//8AAP8AAAD/AAAA/wAAAP//AAD/AAAA/wAAAP/vOnc/\\n4w91P+bTeD9OlXg/lO50P9iadz/QNnk/ysl1PyAedj/m03g/7zp3P+MPdT/Ymnc/TpV4P5Tu\\ndD8gHnY/0DZ5P8rJdT/jD3U/5tN4P+86dz+U7nQ/2Jp3P06VeD/KyXU/IB52P9A2eT+GN3o/\\negx4P37Qez/jkXs/K+t3P26Xej9nM3w/X8Z4P7caeT9+0Hs/hjd6P3oMeD9ul3o/45F7Pyvr\\ndz+3Gnk/ZzN8P1/GeD96DHg/ftB7P4Y3ej8r63c/bpd6P+ORez9fxng/txp5P2czfD8AAAAA\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADNzIw/AAAAAAAA\\nAAAAAAAAzcyMPwAAAAAAAAAAAAAAAM3MjD/NzIw/zcyMP83MjD8AAAD/AAAA/wAAAP//AAD/\\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzcyMPwAA\\nAAAAAAAAAAAAAM3MjD8AAAAAAAAAAAAAAADNzIw/zcyMP83MjD/NzIw/h3WGvImIiLwAAACA\\nzcyMP83MjD8AAACAh3WGvM3MjD8AAACAAAABAL++Pj+/vj4/v74+P83MTD6CIbY+pk86PwAA\\nAAAuVTo/Ygu2PgAAAAAAAMB/AADAfwAAwH8AAMB/AADAfwAAwH8BAQEBAQAAAAABAAAAAIA/\\nAACAPwAAAD8AAAABAQAAAAABAAAAAAA/AAAAPwAAAAABAAABAQAAAAABAAAAAIA/AAAAPwAA\\nAAAAAQABAQAAAAABAAAAAAA/AACAPwAAAAABAQEBAAAAAAABAAAAAIA/AAAAPwAAAD/Py1s/\\nz8tbPwAAAACdWFw/nVhcP6pADj3A+l0/wPpdP2kXjD2DpWA/g6VgP83MzD0oRGQ/KERkP5Wk\\nAz6Gumg/hrpoP8riHD7o5W0/6OVtP6xcMT4YnnM/GJ5zP/VyQD6Ytnk/mLZ5P0qwST4AAIA/\\nAACAP83MTD4AAAABz8tbP8/LWz8AAAAAnVhcP51YXD+qQA49wPpdP8D6XT9pF4w9g6VgP4Ol\\nYD/NzMw9KERkPyhEZD+VpAM+hrpoP4a6aD/K4hw+6OVtP+jlbT+sXDE+GJ5zPxiecz/1ckA+\\nmLZ5P5i2eT9KsEk+AACAPwAAgD/NzEw+zcxMPgAAAAAAAAAA/4RhPuaqxTwAAAAAd6FvPoDF\\nQj0AAAAAWrh2Pj2Ajj0AAAAAeJR2PsNwtz0AAAAA4TZvPjYB2z0AAAAA09ZgPs0m+D0AAAAA\\nJeBLPnEDBz4AAAAAGvAwPrD+DT4AAAAAw9AQPsPQED4AAAAAAAAAAc3MTD4AAAAAAAAAAP+E\\nYT7mqsU8AAAAAHehbz6AxUI9AAAAAFq4dj49gI49AAAAAHiUdj7DcLc9AAAAAOE2bz42Ads9\\nAAAAANPWYD7NJvg9AAAAACXgSz5xAwc+AAAAABrwMD6w/g0+AAAAAMPQED7D0BA+AAAAAJB7\\n7D2Qe+w9kHvsPQCBDD4AgQw+JbnnPTGsHj4xrB4+SjbcPdY3LD7WNyw+3EjKPeW+ND7lvjQ+\\nk3ayPcMBOD7DATg+H3GVPRzoNT4c6DU+9CFoPZqBLj6agS4+K54ePXIFIj5yBSI+e/agPMPQ\\nED7D0BA+AAAAAAAAAAGQe+w9kHvsPZB77D0AgQw+AIEMPiW55z0xrB4+MawePko23D3WNyw+\\n1jcsPtxIyj3lvjQ+5b40PpN2sj3DATg+wwE4Ph9xlT0c6DU+HOg1PvQhaD2agS4+moEuPiue\\nHj1yBSI+cgUiPnv2oDzD0BA+w9AQPgAAAACZmJg+mZiYPpmYmD4AAIA/AAAAAQEBAQAAAA==\"}]},\"context\":{\"shiny\":false,\"rmarkdown\":null},\"vertexShader\":\"#line 2 1\\n// File 1 is the vertex shader\\n#ifdef GL_ES\\n#ifdef GL_FRAGMENT_PRECISION_HIGH\\nprecision highp float;\\n#else\\nprecision mediump float;\\n#endif\\n#endif\\n\\nattribute vec3 aPos;\\nattribute vec4 aCol;\\nuniform mat4 mvMatrix;\\nuniform mat4 prMatrix;\\nvarying vec4 vCol;\\nvarying vec4 vPosition;\\n\\n#ifdef NEEDS_VNORMAL\\nattribute vec3 aNorm;\\nuniform mat4 normMatrix;\\nvarying vec4 vNormal;\\n#endif\\n\\n#if defined(HAS_TEXTURE) || defined (IS_TEXT)\\nattribute vec2 aTexcoord;\\nvarying vec2 vTexcoord;\\n#endif\\n\\n#ifdef FIXED_SIZE\\nuniform vec3 textScale;\\n#endif\\n\\n#ifdef FIXED_QUADS\\nattribute vec3 aOfs;\\n#endif\\n\\n#ifdef IS_TWOSIDED\\n#ifdef HAS_NORMALS\\nvarying float normz;\\nuniform mat4 invPrMatrix;\\n#else\\nattribute vec3 aPos1;\\nattribute vec3 aPos2;\\nvarying float normz;\\n#endif\\n#endif // IS_TWOSIDED\\n\\n#ifdef FAT_LINES\\nattribute vec3 aNext;\\nattribute vec2 aPoint;\\nvarying vec2 vPoint;\\nvarying float vLength;\\nuniform float uAspect;\\nuniform float uLwd;\\n#endif\\n\\n#ifdef USE_ENVMAP\\nvarying vec3 vReflection;\\n#endif\\n\\nvoid main(void) {\\n \\n#ifndef IS_BRUSH\\n#if defined(NCLIPPLANES) || !defined(FIXED_QUADS) || defined(HAS_FOG) || defined(USE_ENVMAP)\\n vPosition = mvMatrix * vec4(aPos, 1.);\\n#endif\\n \\n#ifndef FIXED_QUADS\\n gl_Position = prMatrix * vPosition;\\n#endif\\n#endif // !IS_BRUSH\\n \\n#ifdef IS_POINTS\\n gl_PointSize = POINTSIZE;\\n#endif\\n \\n vCol = aCol;\\n \\n// USE_ENVMAP implies NEEDS_VNORMAL\\n\\n#ifdef NEEDS_VNORMAL\\n vNormal = normMatrix * vec4(-aNorm, dot(aNorm, aPos));\\n#endif\\n\\n#ifdef USE_ENVMAP\\n vReflection = normalize(reflect(vPosition.xyz/vPosition.w, \\n normalize(vNormal.xyz/vNormal.w)));\\n#endif\\n \\n#ifdef IS_TWOSIDED\\n#ifdef HAS_NORMALS\\n /* normz should be calculated *after* projection */\\n normz = (invPrMatrix*vNormal).z;\\n#else\\n vec4 pos1 = prMatrix*(mvMatrix*vec4(aPos1, 1.));\\n pos1 = pos1/pos1.w - gl_Position/gl_Position.w;\\n vec4 pos2 = prMatrix*(mvMatrix*vec4(aPos2, 1.));\\n pos2 = pos2/pos2.w - gl_Position/gl_Position.w;\\n normz = pos1.x*pos2.y - pos1.y*pos2.x;\\n#endif\\n#endif // IS_TWOSIDED\\n \\n#ifdef NEEDS_VNORMAL\\n vNormal = vec4(normalize(vNormal.xyz), 1);\\n#endif\\n \\n#if defined(HAS_TEXTURE) || defined(IS_TEXT)\\n vTexcoord = aTexcoord;\\n#endif\\n \\n#if defined(FIXED_SIZE) && !defined(ROTATING)\\n vec4 pos = prMatrix * mvMatrix * vec4(aPos, 1.);\\n pos = pos/pos.w;\\n gl_Position = pos + vec4(aOfs*textScale, 0.);\\n#endif\\n \\n#if defined(IS_SPRITES) && !defined(FIXED_SIZE)\\n vec4 pos = mvMatrix * vec4(aPos, 1.);\\n pos = pos/pos.w + vec4(aOfs, 0.);\\n gl_Position = prMatrix*pos;\\n#endif\\n \\n#ifdef FAT_LINES\\n /* This code was inspired by Matt Deslauriers' code in \\n https://mattdesl.svbtle.com/drawing-lines-is-hard */\\n vec2 aspectVec = vec2(uAspect, 1.0);\\n mat4 projViewModel = prMatrix * mvMatrix;\\n vec4 currentProjected = projViewModel * vec4(aPos, 1.0);\\n currentProjected = currentProjected/currentProjected.w;\\n vec4 nextProjected = projViewModel * vec4(aNext, 1.0);\\n vec2 currentScreen = currentProjected.xy * aspectVec;\\n vec2 nextScreen = (nextProjected.xy / nextProjected.w) * aspectVec;\\n float len = uLwd;\\n vec2 dir = vec2(1.0, 0.0);\\n vPoint = aPoint;\\n vLength = length(nextScreen - currentScreen)/2.0;\\n vLength = vLength/(vLength + len);\\n if (vLength > 0.0) {\\n dir = normalize(nextScreen - currentScreen);\\n }\\n vec2 normal = vec2(-dir.y, dir.x);\\n dir.x /= uAspect;\\n normal.x /= uAspect;\\n vec4 offset = vec4(len*(normal*aPoint.x*aPoint.y - dir), 0.0, 0.0);\\n gl_Position = currentProjected + offset;\\n#endif\\n \\n#ifdef IS_BRUSH\\n gl_Position = vec4(aPos, 1.);\\n#endif\\n}\",\"fragmentShader\":\"#line 2 2\\n// File 2 is the fragment shader\\n#ifdef GL_ES\\n#ifdef GL_FRAGMENT_PRECISION_HIGH\\nprecision highp float;\\n#else\\nprecision mediump float;\\n#endif\\n#endif\\nvarying vec4 vCol; // carries alpha\\nvarying vec4 vPosition;\\n#if defined(HAS_TEXTURE) || defined (IS_TEXT)\\nvarying vec2 vTexcoord;\\nuniform sampler2D uSampler;\\n#endif\\n\\n#ifdef HAS_FOG\\nuniform int uFogMode;\\nuniform vec3 uFogColor;\\nuniform vec4 uFogParms;\\n#endif\\n\\n#if defined(IS_LIT) && !defined(FIXED_QUADS)\\nvarying vec4 vNormal;\\n#endif\\n\\n#if NCLIPPLANES > 0\\nuniform vec4 vClipplane[NCLIPPLANES];\\n#endif\\n\\n#if NLIGHTS > 0\\nuniform mat4 mvMatrix;\\n#endif\\n\\n#ifdef IS_LIT\\nuniform vec3 emission;\\nuniform float shininess;\\n#if NLIGHTS > 0\\nuniform vec3 ambient[NLIGHTS];\\nuniform vec3 specular[NLIGHTS]; // light*material\\nuniform vec3 diffuse[NLIGHTS];\\nuniform vec3 lightDir[NLIGHTS];\\nuniform bool viewpoint[NLIGHTS];\\nuniform bool finite[NLIGHTS];\\n#endif\\n#endif // IS_LIT\\n\\n#ifdef IS_TWOSIDED\\nuniform bool front;\\nvarying float normz;\\n#endif\\n\\n#ifdef FAT_LINES\\nvarying vec2 vPoint;\\nvarying float vLength;\\n#endif\\n\\n#ifdef USE_ENVMAP\\nvarying vec3 vReflection;\\n#endif\\n\\nvoid main(void) {\\n vec4 fragColor;\\n#ifdef FAT_LINES\\n vec2 point = vPoint;\\n bool neg = point.y < 0.0;\\n point.y = neg ? (point.y + vLength)/(1.0 - vLength) :\\n -(point.y - vLength)/(1.0 - vLength);\\n#if defined(IS_TRANSPARENT) && defined(IS_LINESTRIP)\\n if (neg && length(point) <= 1.0) discard;\\n#endif\\n point.y = min(point.y, 0.0);\\n if (length(point) > 1.0) discard;\\n#endif // FAT_LINES\\n \\n#ifdef ROUND_POINTS\\n vec2 coord = gl_PointCoord - vec2(0.5);\\n if (length(coord) > 0.5) discard;\\n#endif\\n \\n#if NCLIPPLANES > 0\\n for (int i = 0; i < NCLIPPLANES; i++)\\n if (dot(vPosition, vClipplane[i]) < 0.0) discard;\\n#endif\\n \\n#ifdef FIXED_QUADS\\n vec3 n = vec3(0., 0., 1.);\\n#elif defined(IS_LIT)\\n vec3 n = normalize(vNormal.xyz);\\n#endif\\n \\n#ifdef IS_TWOSIDED\\n if ((normz <= 0.) != front) discard;\\n#endif\\n\\n#ifdef IS_LIT\\n vec3 eye = normalize(-vPosition.xyz/vPosition.w);\\n vec3 lightdir;\\n vec4 colDiff;\\n vec3 halfVec;\\n vec4 lighteffect = vec4(emission, 0.);\\n vec3 col;\\n float nDotL;\\n#ifdef FIXED_QUADS\\n n = -faceforward(n, n, eye);\\n#endif\\n \\n#if NLIGHTS > 0\\n // Simulate two-sided lighting\\n if (n.z < 0.0)\\n n = -n;\\n for (int i=0;i