diff --git a/content/blog/2015-04-16-function-two-points-theory.md b/content/blog/2015-04-16-function-two-points-theory.md new file mode 100644 index 0000000..04f79ae --- /dev/null +++ b/content/blog/2015-04-16-function-two-points-theory.md @@ -0,0 +1,25 @@ +--- +id: 65 +title: Math Theory for Function Between Two Points +date: 2015-04-16T22:15:21+00:00 +author: Brandon Rozek +layout: post +guid: http://brandonrozek.com/?p=65 +permalink: /2015/04/function-two-points-theory/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +dsq_thread_id: + - "" + - "" +tumblr_post_id: + - "138122079174" +kind: + - note +--- + + + +[Part1](https://brandonrozek.com/wp-content/uploads/2015/04/Part1.jpeg){.broken_link} +[Part2](https://brandonrozek.com/wp-content/uploads/2015/04/Part2.jpeg){.broken_link} +[Part3](https://brandonrozek.com/wp-content/uploads/2015/04/Part3.jpeg){.broken_link} +[Part4](https://brandonrozek.com/wp-content/uploads/2015/04/Part4.jpeg){.broken_link} \ No newline at end of file diff --git a/content/blog/2015-04-16-responsive-layout-and-animation.md b/content/blog/2015-04-16-responsive-layout-and-animation.md new file mode 100644 index 0000000..26612ae --- /dev/null +++ b/content/blog/2015-04-16-responsive-layout-and-animation.md @@ -0,0 +1,89 @@ +--- +id: 57 +title: Responsive Layout and Animation +date: 2015-04-16T22:19:36+00:00 +author: Brandon Rozek +layout: post +guid: http://brandonrozek.com/?p=57 +permalink: /2015/04/responsive-layout-and-animation/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +dsq_thread_id: + - "3688354609" + - "3688354609" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135656876494" + - "135656876494" +kind: + - article +--- +I saw [Mike Riethmuller’s](http://madebymike.com.au/) precision typography [pen](http://codepen.io/MadeByMike/pen/YPJJYv){.broken_link}, and was highly impressed. I think the equation used has other purposes as well + + + +Side Note: I changed the form of the equation to something similar to y = mx + b so that I can more easily recognize how it functions + +#### Responsive Layout + +There are many occasions where I want an element on the page to move between two points. The navigation in the header of my site (at the time of writing) is a great example of this. So knowing the two points I want it to lie between and having the screen width as the variable, I can plug in… [f(x) = (100 * (b - a)/(d - c))X + (ad - bc) / (d - c)](https://brandonrozek.com/wp-content/uploads/2015/04/responsivelayoutequation.gif){.broken_link} where a is the start pixel b is the end pixel c is the start media query d is the end media query and X is the screen width out of 100 otherwise known as 1vw \*\*Don’t forget to keep track of your units!! Whether it’s px/rem/em/etc.\*\* Say I want to push a box towards the right a minimum of 5px, a maximum of 20px and for the push to vary between the widths 400-800px. Then I would write… + +

+@media (min-width: 400px) and (max-width: 800px) {
+
+.box {
+
+position: relative;
+
+left: calc(3.75vw - 10px) /*After simplifying the equation*/ }
+
+}
+
+ +That would only make it vary between 400-800px. Now we need to include what happens under 400px and over 800px. + +

+@media (max-width: 400px) {
+
+.box {
+
+position: relative;
+
+left: 5px; }
+
+}
+
+@media (min-width: 400px) and (max-width: 800px) {
+
+.box {
+
+position: relative;
+
+left: calc(3.75vw - 10px); }
+
+}
+
+@media (min-width: 800px) {
+
+.box {
+
+position: relative;
+
+left: 20px; }
+
+}
+
+ +This is exactly like Mike’s pen, but instead he uses the equation to adjust the font-size between an upper and lower bound. You can apply this method to anything that accepts calc() and viewport units. Here is my [pen](http://codepen.io/brandonrozek/pen/JoQVEb){.broken_link} showing some use cases. To make your life easier, I made a quick little tool where you can input the variables and it will provide you with a simpler form of the equation to put into your calc() function [here](http://codepen.io/brandonrozek/pen/KpPwGL){.broken_link}. + +#### Animation + +This is where the majority of my research went towards. It’s not as practical as say positioning an element is but I find it interesting. Like, what if I can manipulate the acceleration of the function? [f(x) = ((b - a) / (d^n - c^n))X^n + (ad^n - bc^n) / (d^n - c^n) ](https://brandonrozek.com/wp-content/uploads/2015/04/accelerationequation.gif){.broken_link} Where a is the start unit b is the end unit c is the start time d is the end time n is the acceleration modifier and X is time The interesting part of the function here is the n. If I keep n at 1, then the acceleration is constant. If it’s less than one, then it’s fast in the beginning and slows down at the end. If it’s greater than one, then it’s the opposite. I also made a little pen [here](http://codepen.io/brandonrozek/pen/RNzdOV){.broken_link} to demo this for you. + +#### Conclusion + +Having a function that goes between two points is incredibly handy. Now when it comes to positioning, I don’t have to guess which values match the design. If i cant something to be between here and there fluidly, I can do it. What about animation? Chaining them together should have an interesting affect… P.S For those of you crazy people who like to see the theory behind the math, (like myself) I have my scanned work [here](https://brandonrozek.com/2015/04/function-two-points-theory/). \ No newline at end of file diff --git a/content/blog/2015-05-23-animatable-border.md b/content/blog/2015-05-23-animatable-border.md new file mode 100644 index 0000000..b4a52ce --- /dev/null +++ b/content/blog/2015-05-23-animatable-border.md @@ -0,0 +1,130 @@ +--- +id: 85 +title: 'Animatable: Border' +date: 2015-05-23T19:59:25+00:00 +author: Brandon Rozek +layout: post +guid: http://brandonrozek.com/?p=85 +permalink: /2015/05/animatable-border/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +dsq_thread_id: + - "3807156267" + - "3807156267" +tumblr_post_id: + - "135657818649" + - "135657818649" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +kind: + - article +--- +This is part 1 of an animation series I’m doing. It is inspired by Lea Verou’s talk called “[The Humble Border-Radius.](https://www.youtube.com/watch?v=JSaMl2OKjfQ)” I looked at her site and she has a good demo of a bunch of different animations [here](http://lea.verou.me/2011/10/animatable-a-css-transitions-gallery/). My goal here is to create a more comprehensive guide to these different animatable properties–mainly for future reference. Animations play a big part in adding interactivity to the web, so why not explore some possible options? + + + +This post follows well along with my Codepen [demo](http://codepen.io/brandonrozek/full/waWMWR/){.broken_link}, where I’ll state the box number that applies to what I’m talking about. \*\*Initial values must be explicitly stated, implicit initial values are generally ignored in animation\*\* \*\\*\*In English terms, you must have already stated a value for what you are animating before you animate it\*\** + +### Border-color {#border-color} + + * Accepts 1 to 4 color values + * Each value corresponds to each side of the border (starting from the top and going clockwise) + * Initial Value: currentColor + +Border-color animates by splitting the colors to their red, green and blue components and raises/lowers them to it’s new value. ([Demo](http://codepen.io/brandonrozek/pen/PqzPMe){.broken_link}) ([Spec](http://www.w3.org/TR/css3-transitions/#animtype-color)) Example of animation corresponds to #1 in the pen, but I will rewrite the relevant code here. + +

+@keyframes color {
+
+to { border-color: purple red green blue; }
+
+}
+
+.border-color {
+
+border-color: white;
+
+animation: color .4s ease-in .1s infinite alternate;
+
+}
+
+ +  + +### Border-radius {#border-radius} + + * Accepts 1 to 4 values for both horizontal and vertical radii + * Each value corresponds to a corner starting from the top left and going clockwise + * Initial Value: 0 + +

+.border-radius {
+
+border-radius: 40% 30% 60% 50% / 20% 40% 60% 80%;
+
+/** is the same as **/
+
+border-top-left-radius: 40% 20%;
+
+border-top-right-radius: 30% 40%;
+
+border-bottom-right-radius: 60% 60%;
+
+border-bottom-left-radius: 50% 80%;
+
+/** where the first value is the horizontal radius and the second value the vertical radius**/
+
+}
+
+ +For animation, this corresponds to #2 in the pen I made at the top. I’ll repeat the relevant code here. + +

+
+@keyframes radius {
+
+to { border-radius: 20%; }
+
+}
+
+.border-radius {
+
+border-radius: 0;
+
+animation: radius .5s ease-in .1s infinite alternate;
+
+}
+
+ +  + +### Border-width {#border-width} + + * Accepts 1 to 4 values + * Each value corresponds to a side of the border (starting from the top and going clockwise) + * Initial Value: medium + +For animation, this corresponds to #3 in the pen I made at the top. I’ll repeat the relevant code here. + +

+@keyframes width {
+
+to { border-width: .15rem .25rem .15rem .25rem; }
+
+}
+
+.border-width {
+
+border-width: .7rem;
+
+animation: width .5s ease-in .1s infinite alternate;
+
+}
+
+ +  + +### Conclusion + +Animations are quite enjoyable. The last box in my Codepen demo tries combining all three of those animations. (Super Wacky!)  You don’t need to use keyframe animations to achieve this, you can also use the transition property. I used keyframes so you can better visualize what’s going on. There are plenty of other animatable properties to go through, so I’ll get started on those. In the meantime, if you want to look at some of the sites I used for research I’ll include the links below. {.broken_link} {.broken_link} {.broken_link} \ No newline at end of file diff --git a/content/blog/2015-09-14-animatable-box-model.md b/content/blog/2015-09-14-animatable-box-model.md new file mode 100644 index 0000000..6225cc5 --- /dev/null +++ b/content/blog/2015-09-14-animatable-box-model.md @@ -0,0 +1,194 @@ +--- +id: 155 +title: 'Animatable: Box Model' +date: 2015-09-14T12:07:52+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=155 +permalink: /2015/09/animatable-box-model/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"17293fa1c115";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:66:"https://medium.com/@brandonrozek/animatable-box-model-17293fa1c115";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"17293fa1c115";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:66:"https://medium.com/@brandonrozek/animatable-box-model-17293fa1c115";}' +dsq_thread_id: + - "4130257548" + - "4130257548" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657238924" + - "135657238924" +kind: + - article +--- +This post is part 2 of an animation series I am doing; you can read part 1 [here](https://brandonrozek.com/2015/05/animatable-border/). In this post, we’ll look at the different parts of the box model (margin, padding, height, and width) and see how they can be animated. + + + +The W3C has a great starting reference for the [CSS Box Model](http://www.w3.org/TR/CSS2/box.html). It can be wordy at times, but has everything you need to know. I had never heard of _margin collapsing_ until I read that. Luckily there is a great [post](https://css-tricks.com/what-you-should-know-about-collapsing-margins/) on CSS-Tricks written by Geoff Graham explaining what it is. To see it all in action, take a look at this Codepen [demo](http://codepen.io/brandonrozek/full/RWPYgV/){.broken_link}–  I reference this multiple times in this post. Now, on to the box model. + +### Margin + + * Accepts 1 to 4 numerical values (negative numbers are allowed) + * If you use 4 values, the first value is the top margin and the rest follow in a clockwise fashion + * Initial value: 0 + +Margins can be described as the space around an element. In the Codepen demo (#1), it shows 2 boxes. The first box has a margin-right that is increasing, making it seem as though it’s pushing the second box away. + +

+@keyframes margin {
+
+to { margin-right: 7rem; }
+
+}
+
+.margin {
+
+display: inline-block;
+
+height: 5rem;
+
+width: 5rem;
+
+background-color: lightblue;
+
+vertical-align: top;
+
+}
+
+.margin:first-of-type {
+
+margin-right: 0;
+
+animation: margin 4s ease 0s infinite;
+
+}
+
+ +### Padding + + * Accepts 1 to 4 non-negative values + * If you use 4 values, the first value is the top margin and the rest follow in a clockwise fashion + * Initial value: 0 + +Padding is the space between the content and the border of an element. In the demo (#2),  it shows a box in which its padding is increasing. + +

+@keyframes padding {
+
+to { padding: 2rem; }
+
+}
+
+.padding {
+
+display: inline-block;
+
+padding: 0;
+
+background-color: lightgreen;
+
+animation: padding 2.5s ease 0s infinite;
+
+}
+
+ +### Height + + * Accepts a non-negative number, this number is overridden however by (min/max)-height + * Initial value: auto + +“Height” is the height of an element without its padding, border, or margin. In the demo (#3) you can see the boxes’ height shrink, and each box begins it’s animation at a different time. + +

+@keyframes height {
+
+to { height: .01rem; }
+
+}
+
+.height {
+
+display: inline-block;
+
+height: 4rem;
+
+width: 3rem;
+
+background-color: violet;
+
+animation: height 1.25s ease 0s infinite;
+
+vertical-align: top;
+
+}
+
+.height:nth-of-type(n) {
+
+animation: height 1.25s ease .2s infinite alternate;
+
+}
+
+.height:nth-of-type(2n) {
+
+animation: height 1.25s ease .4s infinite alternate;
+
+}
+
+.height:nth-of-type(3n) {
+
+animation: height 1.25s ease .6s infinite alternate;
+
+}
+
+ +### Width + + * Accepts a non-negative number, this number is overridden however by (min/max)-width + * Initial value: auto + +“Width” is the width of an element without its padding, border, or margin. In the demo (#4), it is similar to #3, however, it’s the width being affected as opposed to the height. + +

+@keyframes width {
+
+to { width: .01rem; }
+
+}
+
+.width {
+
+margin-bottom: .2rem;
+
+height: 3rem;
+
+width: 6.5rem;
+
+background-color: bisque;
+
+}
+
+.width:nth-of-type(n) {
+
+animation: width 1.25s ease .2s infinite alternate;
+
+}
+
+.width:nth-of-type(2n) {
+
+animation: width 1.25s ease .4s infinite alternate;
+
+}
+
+.width:nth-of-type(3n) {
+
+animation: width 1.25s ease .6s infinite alternate;
+
+}
+
+
+ +### Conclusion + +And so with this we can add another collection of animations to our toolbelt! If you’re wondering why I left border out of this box-model post, it’s because I have already written a post dedicated to just the [border animation](https://brandonrozek.com/2015/05/animatable-border/). Here are some of the resources I looked at for this post. Hopefully I’ll come back with another animatable post soon! {.broken_link} {.broken_link} {.broken_link} {.broken_link} \ No newline at end of file diff --git a/content/blog/2015-10-03-animatable-location.md b/content/blog/2015-10-03-animatable-location.md new file mode 100644 index 0000000..1aed8b4 --- /dev/null +++ b/content/blog/2015-10-03-animatable-location.md @@ -0,0 +1,231 @@ +--- +id: 190 +title: 'Animatable: Location' +date: 2015-10-03T09:34:08+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=190 +permalink: /2015/10/animatable-location/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"ad9e6109d5aa";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:65:"https://medium.com/@brandonrozek/animatable-location-ad9e6109d5aa";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"ad9e6109d5aa";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:65:"https://medium.com/@brandonrozek/animatable-location-ad9e6109d5aa";}' +dsq_thread_id: + - "4194325357" + - "4194325357" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657326384" + - "135657326384" +kind: + - article +--- +Animating the location of objects is one of the most common types of animation. It’s interesting to animate this way because you need to keep in mind how each of the element’s interact with each other to constitute a page. + + + +This is part 4 of my series on animation. Check out the other parts of this series! + + * Part 1 — [Animatable: Border](https://brandonrozek.com/2015/05/animatable-border/) + * Part 2 — [Animatable: Box Model](https://brandonrozek.com/2015/09/animatable-box-model/) + * Part 3 — [Animatable: Text](https://brandonrozek.com/2015/10/animatable-text/) + +This post goes along well with this [Codepen demo](http://codepen.io/brandonrozek/full/NGbWzo/){.broken_link}, I’ll reference it multiple times in this post. Now onto animations! + +### background-position + + * Accepts keywords, percentages, or lengths + * Offset-x | Offset-Y + * Initial Value: 0% 0% + +Background-position sets where the background is relative to it’s background-origin. In the Codepen demo (#1), you can see the background image scrolling horizontally. + +
 
+@keyframes background-position {
+ 
+ to { background-position: 100% 0%; }
+
+}
+
+.background-position {
+  background-image: url(https://upload.wikimedia.org/wikipedia/commons/d/d3/Tajik_mountains_edit.jpg);
+
+  height: 6rem;
+
+  width: 8rem;
+
+  background-size: 200% 100%;
+
+  background-position: 0% 0%;
+
+  animation: background-position 5s linear .1s infinite alternate;
+
+}
+
+ +### position with left, right, top, bottom + + * Accepts length, percentage, or some keywords + * Initial value: auto + +The left, right, top, and bottom properties require the position to be set to something other than static. When you add a value to any of these properties just imagine that value pushing the element on that side. For example: for “left: 2rem” imagine that the element is being pushed on the left side by 2rem, making it move to the right 2rem. In the demo (#2), the box is being pushed in a square path. + +

+@keyframes position {
+
+  25% {
+
+    top: 0;
+
+    left: 3rem;
+
+  }
+
+  50% {
+
+    top: 3rem;
+
+    left: 3rem;
+
+  }
+
+  75% {
+
+    top: 3rem;
+
+    left: 0;
+
+  }
+
+}
+
+.position {
+
+  position: relative;
+
+  top: 0;
+
+  left: 0;
+
+  height: 3rem;
+
+  width: 3rem;
+
+  background-color: lightblue;
+
+  animation: position 1.5s ease .1s infinite;
+
+}
+
+ +  + +### vertical-align + + * Accepts keywords, percentages, or lengths (Negative values allowed) + * Initial Value: baseline + +Vertical-align sets how vertically the inline element or text is compared to the baseline. In the Codepen demo (#3), the question has its vertical align being manipulated which causes the “Maybe” to bounce up and down. + +

+@keyframes vertical-align {
+
+  to { vertical-align: 1rem; }
+
+}
+
+.vertical-align {
+
+  font-size: 1.5rem;
+
+  vertical-align: 0;
+
+  animation: vertical-align 1s ease-out .1s infinite alternate;
+
+}
+
+ +### z-index + + * Accepts any integer value + * Initial Value: auto + +If elements overlap, z-index determines which element appears on top. If the z-index is the same, then it is controlled by source order. In the demo (#4), The z-index of the biggest box changes, revealing what is under it. + +

+@keyframes z-index {
+
+  to { z-index: 0; }
+
+}
+
+.z-index {
+
+  position: absolute;
+
+  left: 1rem;
+
+  display: inline-block;
+
+}
+
+.z-index:nth-child(1) {
+
+  height: 1rem;
+
+  width: 1rem;
+
+  background-color: lightgreen;
+
+  z-index: 4;
+
+}
+
+.z-index:nth-child(2) {
+
+  height: 2rem;
+
+  width: 2rem;
+
+  background-color: #F4FFA4;
+
+  z-index: 3;
+
+}
+
+.z-index:nth-child(3) {
+
+  height: 3rem;
+
+  width: 3rem;
+
+  background-color: #DEB0ED;
+
+  z-index: 2;
+
+}
+
+.z-index:nth-child(4) {
+
+  height: 4rem;
+
+  width: 4rem;
+
+  background-color: #D8EADF;
+
+  z-index: 5;
+
+  animation: z-index 1s ease .1s infinite alternate;
+
+}
+
+ +### Conclusion + +By animating the location of an element, it opens up a whole bunch of different opportunities. Using motion, you can signify that the user has indeed pressed the button, instead of what would otherwise leave them there clicking on the button multiple times thinking that nothing has happened. Using motion, you can bring a webpage that would’ve otherwise been boring to life. Use these animations to work, and I’ll be back with another animatable post soon! + +#### The links + + {.broken_link} {.broken_link} {.broken_link} {.broken_link} \ No newline at end of file diff --git a/content/blog/2015-10-03-animatable-text.md b/content/blog/2015-10-03-animatable-text.md new file mode 100644 index 0000000..e91f0ba --- /dev/null +++ b/content/blog/2015-10-03-animatable-text.md @@ -0,0 +1,208 @@ +--- +id: 148 +title: 'Animatable: Text' +date: 2015-10-03T08:44:51+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=148 +permalink: /2015/10/animatable-text/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"8ef239deb1ea";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:61:"https://medium.com/@brandonrozek/animatable-text-8ef239deb1ea";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"8ef239deb1ea";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:61:"https://medium.com/@brandonrozek/animatable-text-8ef239deb1ea";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657083469" + - "135657083469" +kind: + - article +--- +This post is part 3 of my series on animation. In this post, I’ll show you different animations you can add onto text. If you haven’t already, you should check out [part 1](https://brandonrozek.com/2015/09/animatable-box-model/) and [part 2](https://brandonrozek.com/2015/05/animatable-border/) of this series. Animations on text can be used to bring attention, to add importance, or to convey a point. As with all animations, however, keep your user in mind and your text readable. + + + +This post follows along with a [Codepen demo](http://codepen.io/brandonrozek/full/dYGwbE/){.broken_link} I made. + +### line-height + + * Accepts certain keywords, or any positive number or length + * Initial value: normal + +Line-height is the space between each line in a text block. It is commonly recommended that you use a unitless line-height because then it takes the font-size into consideration. When you use an unitless value, the browser determines the line-height by taking the unitless value and multiplying it by the element’s font-size. In the Codepen demo (#1), you can see the line-height decreasing while the opacity increases. + +

+@keyframes line-height {
+
+  to {
+
+    opacity: 1;
+
+    line-height: 1.2;
+
+  }
+
+}
+
+.line-height {
+
+  opacity: 0;
+
+  line-height: 2.5;
+
+  animation: line-height .75s ease .2s infinite;
+
+}
+
+ +### font-weight + + * Accepts certain keywords or 100, 200, 300, 400, 500, 600, 700, 800, 900 (the higher the number, the darker the font-weight) + * Initial value: normal + +Font-weight specifies the boldness of the text. If the typeface doesn’t come with multiple weights, then the animation would only happen between the weights that it does have. In the demo (#2), the text will go from normal weight to bold. + +

+@keyframes font-weight {
+
+  to { font-weight: 900;}
+
+}
+
+.font-weight {
+
+  font-weight: 100;
+
+  animation: font-weight 2s linear .2s infinite alternate;
+
+}
+
+ +### font-size + + * Accepts any length + * Initial value: medium + +It is important to note that changing the font-size could change the value of other text properties that are dependent upon it. (Like unitless line-heights) In the demo (#3), you can see the text’s font-size shrinking. + +

+@keyframes font-size {
+
+  to { font-size: .1rem;}
+
+}
+
+.font-size {
+
+  font-size: 2rem;
+
+  animation: font-size 2s ease-out  .1s infinite;
+
+}
+
+ +### text-shadow + + * Accepts a color and 3 lengths + * Color | Offset-X | Offset-Y | Blur-radius + * Initial value: none + +Text-shadow applies a shadow to both the text and it’s text-decoration. Multiple shadows can be added, and they are applied from front to back. In the animation (#4), you can see the text’s shadow move. + +

+@keyframes text-shadow {
+
+  to { text-shadow: 25px 10px 5px rgba(0, 0, 0, .9);}
+
+}
+
+.text-shadow {
+
+    font-size: 1.5rem;
+
+    text-shadow: -10px 5px 3.5px rgba(0, 0, 0, .3);
+
+    animation: text-shadow 1s ease 0s infinite;
+
+}
+
+ +### text-decoration-color + + * Accepts a color value + * Initial value: currentColor + +This sets the color for [text-decoration-line](https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-line) (underlines, overlines, or strike-throughs) In the demo (#5), the strike-through changes from red to black. + +

+@keyframes text-decoration-color {
+
+  to { text-decoration-color: black;}
+
+}
+
+.text-decoration-color {
+
+  text-decoration-color: red;
+
+  text-decoration-line: line-through;
+
+  animation: text-decoration-color 2s linear 0s infinite alternate;
+
+}
+
+ +### word-spacing + + * Accepts keywords or positive/negative length + * Initial value: normal + +Word-spacing defines the space between tags and words. Negative values bring the words closer to each other. In the demo (#6), you can see the word-spacing increase with ‘good bye!’ where the word ‘bye!’ is moving away. + +

+@keyframes word-spacing {
+
+  to { word-spacing: 5rem;}
+
+}
+
+.word-spacing {
+
+  word-spacing: normal;
+
+  animation: word-spacing 1s ease-in 0s infinite;
+
+}
+
+ +### letter-spacing + + * Accepts keywords or positive/negative length + * Initial value: normal + +Letter-spacing specifies the spacing between text characters. Negative values bring the letters closer together. In the demo (#7), each letter gets separated from one another. + +

+@keyframes letter-spacing {
+
+  to { letter-spacing: 2rem;}
+
+}
+
+.letter-spacing {
+
+  letter-spacing: 0;
+
+  animation: letter-spacing .75s ease 0s infinite alternate;
+
+}
+
+ +### Conclusion + +These animations show the different things you can do with text. Perhaps you’ll add a small animation to a heading to bring depth and attention, or you’ll add some to the text of a button to scream “call to action”. Whatever you decide, I hope this post helped. I’ll see you again next time with another animatable post! 🙂 + +#### The links + +[https://docs.webplatform.org/wiki/css/properties/line-height](https://developer.mozilla.org/en-US/docs/Web/CSS/line-height) {.broken_link} {.broken_link} {.broken_link} {.broken_link} {.broken_link} {.broken_link} \ No newline at end of file diff --git a/content/blog/2015-10-04-html-css-javascript-link-together.md b/content/blog/2015-10-04-html-css-javascript-link-together.md new file mode 100644 index 0000000..6e84abb --- /dev/null +++ b/content/blog/2015-10-04-html-css-javascript-link-together.md @@ -0,0 +1,129 @@ +--- +id: 210 +title: HTML, CSS, Javascript, and how they all link together +date: 2015-10-04T17:50:50+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=210 +permalink: /2015/10/html-css-javascript-link-together/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"9579f30ae529";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:96:"https://medium.com/@brandonrozek/html-css-javascript-and-how-they-all-link-together-9579f30ae529";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"9579f30ae529";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:96:"https://medium.com/@brandonrozek/html-css-javascript-and-how-they-all-link-together-9579f30ae529";}' +dsq_thread_id: + - "4194222476" + - "4194222476" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657370214" + - "135657370214" +kind: + - article +--- +I’ve been teaching a small class on web development recently, and after my first lecture, I’ve gained a newfound respect for teachers. Teaching didn’t come as naturally to me as I would have imagined. I tried going in prepared: with a few outlines and a few code demos. Instead of letting my preparation go to waste, I decided to share them here with you on my site. It’s a nice break from the Animatable posts, so I hope you enjoy! + + + +I suggest a couple short readings to check out before the lecture: + + * [What is CSS](http://www.sitepoint.com/web-foundations/css/) by Adam Roberts + * [Box Model](http://www.w3.org/TR/CSS2/box.html) by the W3C + +Take a quick look if you wish. These are mostly to give an idea of what is going to happen over the next few lectures. What is HTML, CSS, and Javascript? We’ll look into the different parts that form a webpage and how they all interact with each other. + +## HTML + +HTML is where the content of your site lives. It’s also the file the server returns to no matter what, the bare-bones of a webpage. This file may contain text, pictures, and/or other media. + +## CSS + +This is where you style your content. Whether it’s through colors, layout, or typography, there are plenty of different ways for you to visually manipulate your content. + +## Javascript + +Javascript is where you add functionality of your site. Validating user input or having dynamic content are one of the many things you can do with Javascipt. + +## How do they all link together? + +HTML, CSS, and Javascript each do what they do the best. So how can you have them all play nicely on the same ball field? + +### In HTML + +Link the CSS file + +

+  <link rel='stylesheet' href='style.css' />
+
+ +Link the Javascript file + +

+  <script src='script.js'></script>
+
+ +Give the

tag a class of hello and id of world to use in CSS and Javascript + +


+  <p class='hello' id='world'></p>
+
+ +### In CSS + +Refer to any element with class=’hello’ and change it’s text color to red. + +

+.hello { color: red; }
+
+ +Any element with an id=’world’ will have it’s font-size changed to 2rem + +

+#world { font-size: 2rem; }
+
+ +You don’t have to only use the class and id attributes in html, you can refer to any attribute. This code snippet grabs any canvas element with data=’sales’ and changes it’s border to be 5px thick, dashed, and the color blue. + +

+canvas[data=sales] { border: 5px dashed blue; }
+
+ +### In Javascript + +Javascript has many properties and methods you can use to reference different HTML elements To grab (an) element(s) + +

+document.getElementById();
+document.getElementsByClassName(); //Returns an array of element(s)
+document.querySelector(); //Returns the first matching selector
+document.querySelectorAll(); //Returns an array of element(s)
+
+ +To add a class to an element + +

+element.className += “ random-class” //Note the space
+
+ +To check whether a certain condition is true in the browser + +

+window.matchMedia('aspect-ratio: 12/8'); //Returns true if the aspect ratio is 12/8
+window.innerHeight; //Is the height of the window
+window.innerWidth; //Is the width of the window
+
+ +_And a lot more_ + +## What should handle what? + +HTML, CSS, and Javascript should all handle what each of them does best. HTML should handle the content, CSS should handle the styles/presentation, and Javascript should handle the behavior of the webpage. Why, you ask? One reason is that it demonstrates a “separation of concerns”. It would be a mess if you’re writing an article in the HTML and you put style attributes all over the place. That would make the markup confusing and hard to read/edit. + +## Can’t I just put everything in a Javascript file? + +Yes you can, but then you lose some of the great features of HTML and CSS. HTML and CSS ignore everything that it doesn’t understand. When Javascript encounters something it doesn’t understand, it stops running the code completely, regardless of what comes after. Please note that I am only speaking about what gets served to the user. When it comes to what’s actually on your server, then store your content however you wish. + +## Conclusion + +To me personally, my first lecture was a mess. Some of my examples didn’t work properly in the first type-through and I was everywhere. Though, to be sharing the little knowledge I do have, comes with it’s own joy. It must not have gone as terrible as I imagined it in my head because they seemed enthusiastic for the next lecture. So I’m excited to share this outline with you, and hopefully I’ll have many more to come. Until next time. 🙂 \ No newline at end of file diff --git a/content/blog/2015-10-10-javascript-data-types.md b/content/blog/2015-10-10-javascript-data-types.md new file mode 100644 index 0000000..4c0eaef --- /dev/null +++ b/content/blog/2015-10-10-javascript-data-types.md @@ -0,0 +1,311 @@ +--- +id: 238 +title: Javascript Data Types +date: 2015-10-10T20:01:20+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=238 +permalink: /2015/10/javascript-data-types/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"edcd4e2dcf42";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:67:"https://medium.com/@brandonrozek/javascript-data-types-edcd4e2dcf42";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"edcd4e2dcf42";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:67:"https://medium.com/@brandonrozek/javascript-data-types-edcd4e2dcf42";}' +dsq_thread_id: + - "4215821079" + - "4215821079" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657462089" + - "135657462089" +kind: + - article +--- +Javascript has multiple ways you can store your data. Each of these different ways is called a data type, and they each carry different “methods” which are helpful commands. Today, I’ll show you the different data types and methods that I use and how they’re useful. + + + +This post is by far not a comprehenive list of all the Data types and their methods. If you want one of those, please check out [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects) and/or [WebPlatform](http://docs.webplatform.org/wiki/javascript/objects){.broken_link}. This is the second lecture of the web development class I’m teaching for the newer folks over at [Math I/O](http://math-io.com). Due to the nature of Math I/O (making math games and all), the next few posts will be Javascript centric. We’re getting ready to build a new game, so I want to prepare them as much as possible. \*Excited\* ^_^ Ilya Kantor does a good job of descibing Javascript data types and their many methods in [Mastering Data Types](http://javascript.info/tutorial/mastering-data-types) which I made the recommended reading for this lecture. + +### String {#string} + +A string is one or more characters. + +
var name = "Brandon";
+ +You can access a character inside of a string by using [] notation. Inside the [] you put the index of the character you want. An index is the numeral location of the character starting from the left. It is important to note that Javascript starts counting from 0. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ B + + r + + a + + n + + d + + o + + n +
+ + 1 + + 2 + + 3 + + 4 + + 5 + + 6 +
+ +
var firstInitial = "Brandon"[0];
+ +Now the value of firstInitial is the letter "B". + +#### Some useful methods for strings {#some-useful-methods-for-strings} + +##### String.prototype.indexOf(); {#string.prototype.indexof();} + +This can be used to find the index of any character(s) in a string. I primarily use it for when I need to check if something exists in a string. Do I have a ‘z’ in my name? + +
"Brandon".indexOf('z');
+ +Nope, so Javascript will return a -1. How about a ‘d’? + +
"Brandon".indexOf('d');
+ +Yes, Javascript will return 5 which is the index of the letter ‘d’. + +##### String.prototype.replace(); {#string.prototype.replace();} + +The replace method can replace any character(s) with other character(s). For more complex replacing, look into [Regular Expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) and how you can use them in .replace(). Replace the first ‘n’ in my name with an ‘m’. + +

+var modifiedName = "Brandon".replace('n', 'm');
+
+console.log(modifiedName);
+
+ +Logs "Bramdon". + +##### String.prototype.toUpperCase(); {#string.prototype.touppercase();} + +This method returns the string with all the lowercase characters converted to uppercase and can be useful for when you’re checking user input and you don’t want to worry about different cases. + +
"Brandon".toUpperCase();
+ +Returns "BRANDON". + +##### String.prototype.toLowerCase(); {#string.prototype.tolowercase();} + +Same as above but instead of converting lowercase to uppercase, it converts uppercase to lowercase. + +
"Brandon".toLowerCase();
+ +Returns "brandon". + +#### A couple useful escape secquences {#a-couple-useful-escape-secquences} + + * n for newline. + * t for tab character. + +You can also use escape sequnces if you want to add “” or ‘’ to your strings. + +

+var greeting = "Hello "Brandon"";
+
+console.log(greeting);
+
+ +Returns "Hello "Brandon"". + +### Number {#number} + +Any number between -(253 – 1) and (253 – 1). + +#### Number Methods {#number-methods} + +Number methods are useful when trying to represent complex numbers. + +##### Number.prototype.toExponential(); {#number.prototype.toexponential();} + +Returns a string representing a number in exponential notation. + +
77.1234.toExponential(2);
+ +Returns "7.71e+1". + +##### Number.prototype.toFixed(); {#number.prototype.tofixed();} + +Returns a string representing a number fixed to x amount of decimal places. + +
12345.6789.toFixed(1);
+ +Returns "12345.7". + +##### Number.prototype.toPrecision(); {#number.prototype.toprecision();} + +Returns a string representing a number using x amount of significant figures. + +
5.123456.toPrecision(2);
+ +Returns "5.1". + +#### Math properties/methods {#math-properties/methods} + +In Javascript there is a Math object which contains many properties and methods which are useful for mathmatical calculations. + +##### Return Euler’s constant {#return-euler's-constant} + +Math.E which returns ~2.718. + +##### Return the natural log of x {#return-the-natural-log-of-x} + +Math.log(x) + +##### Rise x to the y power {#rise-x-to-the-y-power} + +Math.pow(x,y) + +##### Return a psuedo random number [0,1) {#return-a-psuedo-random-number-[0,1)} + +Math.random() + +##### Round x to the nearest integer {#round-x-to-the-nearest-integer} + +Math.round(x) + +### Boolean {#boolean} + +Booleans are either true or false and are typically used in conditional statements. You can either create them explicitly + +
var alive = true;
+ +or by evaluating a [comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators). + +

+var dead = false;
+var isAlive = !dead;
+
+ +isAlive equals true. + +### Array {#array} + +An array is a list of items. In Javascript these items can be any data type, even arrays themselves. + +
var mixedBag = ['sword', 24, true, [Math.PI, Math.E], 'shield'];
+ +To access an item in an array use [] notation with an index as mentioned over at strings. + +
['sword', 'shield', 'helmet'][1];
+ +Returns 'shield'. to figure out how many items are in the array. + +

+var inventory = ['boots', 'gloves', 'pants', 'shirt'];
+var inventoryAmt = inventory.length;
+
+ +inventoryAmt is 4 since there are 4 items in inventory. + +#### Array Methods {#array-methods} + +##### Array.prototype.push(); {#array.prototype.push();} + +Adds whatever is inside the parenthesis to the end of the array. Great for adding items to a list. For example, test scores. + +
[100,92,95].push(80);
+ +Returns [100,92,95,80]. + +##### Array.prototype.reverse(); {#array.prototype.reverse();} + +Reverses the order of all the items in the array. + +
[1,2,3].reverse();
+ +Returns [3,2,1]. + +##### Array.prototype.concat(); {#array.prototype.concat();} + +Combines two arrays, putting the items from the array in the parenthesis to the end of the main array. This method is a lot faster than grabbing each item by their index and adding them using the .push() method. + +
['a','b','c'].concat([1,2,3]);
+ +Returns ['a','b','c',1,2,3]. + +##### Array.prototype.join(); {#array.prototype.join();} + +Converts the array into a string, with each item seperated by whatever is in the parenthesis. Useful for telling the user the items in their inventory, for example. + +

+var inventory = ['books','apples','pencils'];
+console.log("You have " + inventory.join(", ") + " in your inventory.");
+
+ +Logs "You have books, apples, pencils in your inventory." + +##### Array.prototype.indexOf(); {#array.prototype.indexof();} + +Similar to String.prototype.indexOf(), it returns the index of the item inside the parenthesis. + +
['chicken','pizza','tacos'].indexOf('tacos');
+ +Returns 2. + +### Objects {#objects} + +Objects are like arrays, however they’re easier for establishing the relationship between properties and their values. You can store any data type as a property of an object. + +

+var player = {};
+player.name = "Brandon";
+player.health = Number.POSITIVE_INFINITY;
+console.log(player.name + " has " + player.health + " health.");
+
+ +Logs "Brandon has Infinity health" Yup that sounds about right. + +### Conclusion {#conclusion} + +All of the different data types in Javascript are tools for you to get the job done. When assigning a variable, think to yourself which tool you should use. I had fun doing this lecture. We finished earlier than expected, due to my extra preparations. (Still shuddering over my unpreparedness from last week). We had finished so early in fact, that I went ahead and started teaching next week’s material. Do not worry though, my lovely reader’s only get the most structured of lesson materials. So you’ll have to wait until next week to hear more. 🙂 \ No newline at end of file diff --git a/content/blog/2015-10-11-animatable-visual.md b/content/blog/2015-10-11-animatable-visual.md new file mode 100644 index 0000000..25d16b2 --- /dev/null +++ b/content/blog/2015-10-11-animatable-visual.md @@ -0,0 +1,119 @@ +--- +id: 297 +title: 'Animatable: Visual' +date: 2015-10-11T16:52:36+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=297 +permalink: /2015/10/animatable-visual/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"c1119f67e27a";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:63:"https://medium.com/@brandonrozek/animatable-visual-c1119f67e27a";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"c1119f67e27a";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:63:"https://medium.com/@brandonrozek/animatable-visual-c1119f67e27a";}' +tumblr_post_id: + - "135657496179" + - "135657496179" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +kind: + - article +--- +Hello everyone! This is part 5 of my series on animation. Today’s post will be short, since we’re only going to talk about color and opacity. + + + +I’ll give a shout-out to , if you are interested in [CSS Animation performance](https://blogs.adobe.com/webplatform/2014/03/18/css-animations-and-transitions-performance/), then check them out to see what triggers a repaint and/or reflow. Take a look at the other posts in this series! + + * Part 1 — [Animatable: Border](https://brandonrozek.com/2015/05/animatable-border/) + * Part 2 — [Animatable: Box Model](https://brandonrozek.com/2015/09/animatable-box-model/) + * Part 3 — [Animatable: Text](https://brandonrozek.com/2015/10/animatable-text/) + * Part 4 — [Animatable: Location](https://brandonrozek.com/2015/10/animatable-location/) + +This post goes with a [Codepen demo](http://codepen.io/brandonrozek/full/rOzeyO/){.broken_link} I made, I’ll reference it later in this post. + +### color {#color} + + * Accepts any [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) value + * Typically inherits it’s color from the parent element + +The color property sets the color of an element’s text content and its decoration. During the animation, the browser sees the colors in their red, green, and blue (rgb) components, then increments/decrements those values until it reaches the color it’s animating to. For example, in the Codepen demo (#1), the color of the text is changing from red or rgb(255, 0, 0) to green or rgb(0, 255, 0). Meaning the red component is going from 255 to 0 and the green component is going from 0 to 255 during the animation. + +
@keyframes color {
+
+  to { color: green; }
+
+}
+
+.color {
+
+  font-size: 2rem;
+
+  color: red;
+
+  text-decoration: underline;
+
+  animation: color 1.5s ease-in 0s infinite alternate;
+
+}
+
+ +### opacity {#opacity} + + * Accepts any number from [0, 1] + * Initial Value: 1 + +Opacity sets the transparency of an element and it’s decendants. Unlike display: none;, when the element is opacity: 0; the element still holds it’s space on the page. In the Codepen demo (#2), you can see the element and it’s children fading out. + +
@keyframes opacity {
+
+  to { opacity: 0; }
+
+}
+
+.opacity {
+
+  height: 5rem;
+
+  width: 5rem;
+
+  background-color: #cd86e4;
+
+  opacity: 1;
+
+  animation: opacity 2s linear 0s infinite alternate;
+
+}
+
+.opacity div {
+
+  margin-left: auto;
+
+  margin-right: auto;
+
+  height: 3rem;
+
+  width: 3rem;
+
+  background-color: lightblue;
+
+}
+
+.opacity div div {
+
+  margin-left: auto;
+
+  margin-right: auto;
+
+  height: 1rem;
+
+  width: 1rem;
+
+  background-color: #00b300;
+
+}
+
+ +### Conclusion {#conclusion} + +I used to work on a chat application called Babbler. In it, I used opacity to fade in the messages as the user recieved them. With all these different types of animations, you can visually show the user what’s going on in your website/application. Doing this series helps me, (as well as you, I hope) recognize all the different properties and possibilities for animation. This is the second to last part of this series, meaning that the next part is the finale. I’m somewhat sad to see this series ending but excited at the same time. Until next time, have fun animating. 🙂 \ No newline at end of file diff --git a/content/blog/2015-10-18-animatable-transform.md b/content/blog/2015-10-18-animatable-transform.md new file mode 100644 index 0000000..13e596e --- /dev/null +++ b/content/blog/2015-10-18-animatable-transform.md @@ -0,0 +1,144 @@ +--- +id: 337 +title: 'Animatable: Transform' +date: 2015-10-18T16:32:37+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=337 +permalink: /2015/10/animatable-transform/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"1eb4fcf6a5df";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:66:"https://medium.com/@brandonrozek/animatable-transform-1eb4fcf6a5df";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"1eb4fcf6a5df";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:66:"https://medium.com/@brandonrozek/animatable-transform-1eb4fcf6a5df";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657540174" + - "135657540174" +kind: + - article +--- +This is the last post of the animatable series. The grand finale. Here, we will talk about the transform property. It’s only one property but it comes with a lot of goodies in the form of transform-functions. + + + +This is not a comprehensize list. If you want one of those, please check out MDN. They have a great [resource](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function). This is the last post of the animatable series, I recommend you check out the other parts too. + + * Part 1 — [Animatable: Border](https://brandonrozek.com/2015/05/animatable-border/) + * Part 2 — [Animatable: Box Model](https://brandonrozek.com/2015/09/animatable-box-model/) + * Part 3 — [Animatable: Text](https://brandonrozek.com/2015/10/animatable-text/) + * Part 4 — [Animatable: Location](https://brandonrozek.com/2015/10/animatable-location/) + * Part 5 — [Animatable: Visual](https://brandonrozek.com/2015/10/animatable-visual/) + +Animatable: Transform goes with a [CodePen demo](http://codepen.io/brandonrozek/full/ojoMyE){.broken_link} I made. Please check it out, as I will be referencing it later on in the post. + +### rotate() {#rotate()} + +The rotate() function moves the element around a fixed point as defined by the [transform-origin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin) property. In the Codepen demo (#1), the star continously rotates 360 degrees. + +
@keyframes rotate {
+
+  to { transform: rotate(360deg);}
+
+}
+
+.rotate {
+
+  width: 6rem;
+
+  height: 6rem;
+
+  background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Star_full.svg/2000px-Star_full.svg.png");
+
+  background-size: cover;
+
+  transform: none;
+
+  animation: rotate 1s ease 0s infinite;
+}
+
+ +### scale() {#scale()} + +Scale(sx, sy) modifies the size of the element by taking 2 arguments: sx and sy. Where sx is the multiplier that scales the element in the x-direction while sy is the multiplier that scales the element in the y-direction. In the CodePen demo (#2), the little ninja man scales to half his size and back to normal again. + +
@keyframes scale {
+
+  to { transform: scale(.5); }
+
+}
+
+.scale {
+
+  width: 6rem;
+
+  height: 6rem;
+
+  background-image: url("https://upload.wikimedia.org/wikipedia/commons/7/71/Monocromaticman.JPG");
+
+  background-size: contain;
+
+  background-repeat: no-repeat;
+
+  transform: none;
+
+  animation: scale 1s ease 0s infinite alternate;
+}
+
+ +### skew() {#skew()} + +Skew distorts the element by moving each point to a certain angle determined by it’s distance from the origin. In the CodePen demo (#3), the square skews -20 degrees, making it appear as a parallelogram. + +
@keyframes skew {
+
+  to { transform: skew(-20deg); }
+
+}
+
+.skew {
+
+  height: 6rem;
+
+  width: 6rem;
+
+  background-color: lightblue;
+
+  transform: none;
+
+  animation: skew .75s ease 0s infinite alternate;
+}
+
+ +### translate() {#translate()} + +Transform(tx, ty) moves the element as specified by it’s two parameters tx and ty. Tx tells the browser how many units to move it in the x direction while ty tells the browser how many units to move the element in the y direction. In the CodePen demo (#4), the car moves forward 10rem and back again. + +
@keyframes translate {
+
+  to { transform: translate(10rem);}
+
+}
+
+.translate {
+
+  height: 6rem;
+
+  width: 6rem;
+
+  background-image: url("http://res.freestockphotos.biz/pictures/15/15685-illustration-of-a-red-cartoon-car-pv.png");
+
+  background-size: contain;
+
+  background-repeat: no-repeat;
+
+  transform: none;
+
+  animation: translate 1s ease 0s infinite alternate;
+}
+
+ +### Conclusion {#conclusion} + +It is now the end of the Animatable series. I am sad to see this first completed series of mine go. It’s okay though, I’m bound to think of another series to write for you guys in no time. My goal in Animatable, is to show you (and me) what is possible using CSS animations. With this small reference completed, we have a good overview of the different tools available. Now with our new toolbelt, go out and craft meaningful experinces! \ No newline at end of file diff --git a/content/blog/2015-10-18-javascript-conditional-statements.md b/content/blog/2015-10-18-javascript-conditional-statements.md new file mode 100644 index 0000000..8497661 --- /dev/null +++ b/content/blog/2015-10-18-javascript-conditional-statements.md @@ -0,0 +1,101 @@ +--- +id: 344 +title: Javascript Conditional Statements +date: 2015-10-18T18:30:21+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=344 +permalink: /2015/10/javascript-conditional-statements/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"72ac61ee8d04";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:79:"https://medium.com/@brandonrozek/javascript-conditional-statements-72ac61ee8d04";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"72ac61ee8d04";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:79:"https://medium.com/@brandonrozek/javascript-conditional-statements-72ac61ee8d04";}' +dsq_thread_id: + - "4237729275" + - "4237729275" +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657634939" + - "135657634939" +kind: + - article +--- +Javascript, like most other programming languages, include ways to run blocks of code when something meets a condition. Here, I will describe the most common ways to do so. + + + +This post is part of my lecture series for Math I/O. There is no pre-reading for this lecture. + +### If Statement {#if-statement} + +To run a block of code when a condition is true, use an if statement. + +
    if (condition) {
+        doSomething();
+    }
+
+ +You can also run a block of code when a condition is false using the else statement. + +
    if (condition) {
+        doSomething();
+    } else {
+        doSomethingElse();
+    }
+
+ +### Switch statement {#switch-statement} + +If you want to check a variable for **equality** against multiple different cases, use a switch statement. + +
    switch (variable) {
+        case condition1:
+            doSomething();
+            break;
+        case condition2:
+            doSomethingElse();
+            break;
+        default:
+            doSomethingCompletelyDifferent();
+            break;
+    }
+
+ +The default statement runs when the variable doesn’t equal any of the cases. + +### While loop {#while-loop} + +To run a block of code over and over again until a condition is false, use a while loop. + +
    while (condition) {
+        doSomething();
+    }
+
+ +Don’t forget to include something in the loop that will eventually make the condition false, otherwise you run into an infinite loop. (Which is a loop that never stops repeating itself; most likely crashing your browser) + +### For loop {#for-loop} + +If you want to run something a certain amount of times, use a “for" loop. For loops can be broken down into three components: an initiating statement, a condition, and a statement that runs after every loop. + +
    for (var i = 0; i < 5; i++) {
+        doSomething();
+    }
+
+ +Here you have the initiating statement of var i = 0. From there you check, is i less than 5? Yes, so then we doSomething();. After we doSomething();, we add 1 to i. Now i equals 2. Is i still less than 5? Yes, so we doSomething();. Then we add 1 to i again. This loop will keep happening until i is not less than 5. + +### Conclusion {#conclusion} + +Having different control/conditional statements helps keep the state of any application you’re making. Did the user say not to notify them? Then don’t, otherwise (else) notify them. That’s all I have to say for this week. Hope this post helps you get a little more used to this big world called programming. + +
    if (youLikeThisPost) {
+        console.log("Come back next week! :)");
+    } else {
+        console.log("Aww that's okay, you should give me another chance next week :)");
+    }
+
+ +I recommend that you look at different perspectives of the same concepts. WebCheatSheet.com has a similar post to mine, check out what they had to say [here](http://webcheatsheet.com/javascript/if_else_switch.php). \ No newline at end of file diff --git a/content/blog/2015-10-25-functions.md b/content/blog/2015-10-25-functions.md new file mode 100644 index 0000000..713fb45 --- /dev/null +++ b/content/blog/2015-10-25-functions.md @@ -0,0 +1,115 @@ +--- +id: 350 +title: Functions +date: 2015-10-25T13:48:41+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=350 +permalink: /2015/10/functions/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"44583f68d3fa";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:55:"https://medium.com/@brandonrozek/functions-44583f68d3fa";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"44583f68d3fa";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:55:"https://medium.com/@brandonrozek/functions-44583f68d3fa";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657661534" + - "135657661534" +kind: + - article +--- +Ever had a snippet of code that appears multiple times in different places in your program? Whenever you had to change that snippet, you end up playing this game of search and replace. Functions can help. They exist to abstract your code, making it not only easier to change that little snippet, but to read and debug your code as well. + + + +### How to create/execute a function {#how-to-create/execute-a-function} + +To make a function + +
    
+    var doSomething = function() {
+        doStuff;
+    }
+
+ +To call the above function to execute + +

+    doSomething();
+
+ +### Arguments {#arguments} + +You can also add in arguments (parameters that go inside the paraenthesis next to the word function) for the functions to use. + +

+    var add = function(number1, number2) {
+        return number1 + number2;
+    }
+
+ +And when you use the `return` keyword, like the function above. You can store the value in a variable for future use. + +
    
+    var total = add(1, 3);
+
+ +total here will equal `4` + +### Scope {#scope} + +Functions create their own scope, which means that variables created inside the function will only be able available within that function. + +The snippet below will output an error like total is not defined + +

+    var add = function(number1, number2) {
+        var total = number1 + number2;
+    }
+    console.log(total);
+
+ +Below is a correct example of the concept + +

+    //Function below converts km/hr to m/s
+    var convert = function(speed) {
+        var metersPerHour = speed * 1000;
+        var metersPerSecound = metersPerHour / 3600;
+        return metersPerSecond;
+    }
+    var currentSpeed = convert(5);
+
+ +It’s also important to note that functions can use variables outside of it; granted it resides in the same scope. + +Here is an example of a variable that doesn’t reside in the same scope as the function. (The below code will fail) + +

+    var something = function() {
+        var x = 5;
+        var y = 2;
+    }
+    something();
+    var addXandY = function() {
+        console.log(x + y);
+    }
+    addXandY();
+
+ +Below, is an example of where the variable does reside in the same scope as the function. Which allows this snippet to execute properly. + +

+    var x = 5;
+    var addX = function(a) {
+        return a + x;
+    }
+    var sum = addX(6);
+
+ +sum here will equal 11 + +### Conclusion {#conclusion} + +As long as you name them appropriately, functions are useful for abstracting your code, making them easier to understand. This concludes another lecture made for the members over at Math I/O. Until next week 🙂 \ No newline at end of file diff --git a/content/blog/2015-11-14-service-workers.md b/content/blog/2015-11-14-service-workers.md new file mode 100644 index 0000000..75d81d8 --- /dev/null +++ b/content/blog/2015-11-14-service-workers.md @@ -0,0 +1,362 @@ +--- +id: 400 +title: An Offline Experience with Service Workers +date: 2015-11-14T15:47:06+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=400 +permalink: /2015/11/service-workers/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"125e50979ed8";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:88:"https://medium.com/@brandonrozek/an-offline-experience-with-service-workers-125e50979ed8";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"125e50979ed8";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:88:"https://medium.com/@brandonrozek/an-offline-experience-with-service-workers-125e50979ed8";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657690564" + - "135657690564" +kind: + - article +--- +I’m excited to say that I’ve written my first service worker for brandonrozek.com. What is a service worker? A service worker provides an extra layer between the client and the server. The exciting part about this is that you can use service workers to deliver an offline experience. (Cached versions of your site, offline pages, etc.) + + + +Service workers are currently supported in Chrome, Opera, and Firefox nightly. You don’t have to worry too much about browser support because the Service Worker spec was written in a [progressively enchanced](http://alistapart.com/article/understandingprogressiveenhancement) way meaning it won’t break your existing site 🙂 + +## Caveats {#caveats} + +You need HTTPS to be able to use service workers on your site. This is mainly for security reasons. Imagine if a third party can control all of the networking requests on your site? If you don’t want to go out and buy a SSL Certificate, there are a couple free ways to go about this. 1) [Cloudflare](https://www.cloudflare.com/) 2) [Let’s Encrypt](https://letsencrypt.org/) Service workers are promise heavy. Promises contain a then clause which runs code asynchronously. If you’re not accustomed to this idea please check out this [post](https://ponyfoo.com/articles/es6-promises-in-depth) by Nicolas Bevacqua. Now onto making the service worker! If you want to skip to the final code scroll down to the bottom. Unless you don’t like my syntax highlighting, then you can check out this [gist](https://gist.github.com/brandonrozek/0cf038df40a913fda655). + +## Register the service worker {#register-the-service-worker} + +Place `service-worker.js` on the root of your site. This is so the service worker can access all the files in the site. Then in your main javascript file, register the service worker. + +

+if (navigator.serviceWorker) {
+  navigator.serviceWorker.register('/serviceworker.js', {
+    scope: '/'
+  });
+}
+
+ +## Install the service worker {#install-the-service-worker} + +The first time the service worker runs, it emits the `install` event. At this time, we can load the visitor’s cache with some resources for when they’re offline. Every so often, I like to change up the theme of the site. So I have version numbers attached to my files. I would also like to invalidate my cache with this version number. So at the top of the file I added + +

+var version = 'v2.0.24:';
+
+ +Now, to specify which files I want the service worker to cache for offline use. I thought my home page and my offline page would be good enough. + +

+var offlineFundamentals = [
+    '/',
+    '/offline/'
+];
+
+ +Since cache.addAll() hasn’t been implemented yet in any of the browsers, and the polyfill implementation didn’t work for my needs. I pieced together my own. + +

+var updateStaticCache = function() {
+    return caches.open(version + 'fundamentals').then(function(cache) {
+        return Promise.all(offlineFundamentals.map(function(value) {
+            var request = new Request(value);
+            var url = new URL(request.url);
+            if (url.origin != location.origin) {
+                request = new Request(value, {mode: 'no-cors'});
+            }
+            return fetch(request).then(function(response) {
+                var cachedCopy = response.clone();
+                return cache.put(request, cachedCopy);
+            });
+        }))
+    })
+};
+
+ +Let’s go through this chunk of code. + + 1. Open the cache called 'v2.0.24:fundamentals' + 2. Go through all of the offlineFundamental‘s URLs + * Does the file I ask for come from the same domain as my site? + * No. Then, make the request ‘no-cors’ (I had difficulty getting my asset files in cors mode. If the cors headers are included in the response, then you can take out this line) + * Fetch the file from the network and then cache it. + +Now we call it when the `install` event is fired. + +

+self.addEventListener("install", function(event) {
+    event.waitUntil(updateStaticCache())
+})
+
+ +With this we now cached all the files in the offlineFundamentals array during the install step. + +## Clear out the old cache {#clear-out-the-old-cache} + +Since we’re caching everything. If you change one of the files, your visitor wouldn’t get the changed file. Wouldn’t it be nice to remove old files from the visitor’s cache? Every time the service worker finishes the install step, it releases an `activate` event. We can use this to look and see if there are any old cache containers on the visitor’s computer. From [Nicolas’ code](https://ponyfoo.com/articles/serviceworker-revolution). Thanks for sharing 🙂 + +

+var clearOldCaches = function() {
+    return caches.keys().then(function(keys) {
+            return Promise.all(
+                      keys
+                        .filter(function (key) {
+                              return key.indexOf(version) != 0;
+                        })
+                        .map(function (key) {
+                              return caches.delete(key);
+                        })
+                );
+        })
+}
+
+ + 1. Check the names of each of the cache containers + 2. If they don’t start with the correct version number + * Delete that cache container + +Call the function when the `activate` event fires. + +

+self.addEventListener("activate", function(event) {
+    event.waitUntil(clearOldCaches())
+});
+
+ +## Intercepting fetch requests {#intercepting-fetch-requests} + +The cool thing about service worker’s is that it can handle file requests. We could cache all files requested for offline use, and if a fetch for a resource failed, then the service worker can look for it in the cache or provide an alternative. This is a large section, so I’m going to attempt to break it down as much as I can. + +### Limit the cache {#limit-the-cache} + +If the visitor started browsing all of the pages on my site, his or her cache would start to get bloated with files. To not burden my visitors, I decided to only keep the latest 25 pages and latest 10 images in the cache. + +

+var limitCache = function(cache, maxItems) {
+    cache.keys().then(function(items) {
+        if (items.length > maxItems) {
+            cache.delete(items[0]);
+        }
+    })
+}
+
+ +We’ll call it later in the code. + +### Fetch from network and cache {#fetch-from-network-and-cache} + +Every time I fetch a file from the network I throw it into a specific cache container. 'pages' for HTML files, 'images' for CSS files, and 'assets' for any other file. This is so I can handle the cache limiting above easier. Defined within the `fetch` event. + +

+var fetchFromNetwork = function(response) {
+        var cacheCopy = response.clone();
+        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            caches.open(version + 'pages').then(function(cache) {
+                cache.put(event.request, cacheCopy).then(function() {
+                    limitCache(cache, 25);
+                })
+            });
+        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+            caches.open(version + 'images').then(function(cache) {
+                cache.put(event.request, cacheCopy).then(function() {
+                    limitCache(cache, 10); 
+                });
+            });
+        } else {
+            caches.open(version + 'assets').then(function add(cache) {
+                cache.put(event.request, cacheCopy);
+            });
+        }
+
+        return response;
+    }
+
+ +### When the network fails {#when-the-network-fails} + +There are going to be times where the visitor cannot access the website. Maybe they went in a tunnel while they were riding a train? Or maybe your site went down. I thought it would be nice for my reader’s to be able to look over my blog posts again regardless of an internet connection. So I provide a fall-back. Defined within the `fetch` event. + +

+var fallback = function() {
+        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            return caches.match(event.request).then(function (response) { 
+                return response || caches.match('/offline/');
+            })
+        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+            return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' }});
+        } 
+    }
+
+ + 1. Is the request for a HTML file? + * Show the [offline](https://brandonrozek.com/offline/) page. + 2. Is the request for an image? + * Show a place-holder image (Courtesy of [Jeremy Keith](https://adactio.com/journal/9775)) + +### Handle the request {#handle-the-request} + +First off, I’m only handling GET requests. + +

+if (event.request.method != 'GET') {
+        return;
+}
+
+ +For HTML files, grab the file from the network. If that fails, then look for it in the cache. _Network then cache strategy_ + +

+if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
+        return;
+        }
+
+ +For non-HTML files, follow this series of steps + + 1. Check the cache + 2. Does a cache exist for this file? + * Yes. Then show it + * No. Then grab it from the network and cache it. + +_Cache then network strategy_ + +

+event.respondWith(
+        caches.match(event.request).then(function(cached) {
+            return cached || fetch(event.request).then(fetchFromNetwork, fallback);
+        })
+    )
+
+ +For different stategy’s, take a look at Jake Archibald’s [offline cookbook](https://jakearchibald.com/2014/offline-cookbook/). + +## Conclusion {#conclusion} + +With all of that, we now have a fully functioning offline-capable website! I wouldn’t be able to implement this myself if it wasn’t for some of the awesome people I mentioned earlier sharing their experience. So share, share, share! With that sentiment, I’ll now share the full code for `service-worker.js` **Update:** There is a new version of this code over at this [blog post](https://brandonrozek.com/2015/11/limiting-cache-service-workers-revisited/). + +

+var version = 'v2.0.24:';
+
+var offlineFundamentals = [
+    '/',
+    '/offline/'
+];
+
+//Add core website files to cache during serviceworker installation
+var updateStaticCache = function() {
+    return caches.open(version + 'fundamentals').then(function(cache) {
+        return Promise.all(offlineFundamentals.map(function(value) {
+            var request = new Request(value);
+            var url = new URL(request.url);
+            if (url.origin != location.origin) {
+                request = new Request(value, {mode: 'no-cors'});
+            }
+            return fetch(request).then(function(response) {
+                var cachedCopy = response.clone();
+                return cache.put(request, cachedCopy);
+            });
+        }))
+    })
+};
+
+//Clear caches with a different version number
+var clearOldCaches = function() {
+    return caches.keys().then(function(keys) {
+            return Promise.all(
+                      keys
+                        .filter(function (key) {
+                              return key.indexOf(version) != 0;
+                        })
+                        .map(function (key) {
+                              return caches.delete(key);
+                        })
+                );
+        })
+}
+
+/*
+    limits the cache
+    If cache has more than maxItems then it removes the first item in the cache
+*/
+var limitCache = function(cache, maxItems) {
+    cache.keys().then(function(items) {
+        if (items.length > maxItems) {
+            cache.delete(items[0]);
+        }
+    })
+}
+
+
+//When the service worker is first added to a computer
+self.addEventListener("install", function(event) {
+    event.waitUntil(updateStaticCache())
+})
+
+//Service worker handles networking
+self.addEventListener("fetch", function(event) {
+
+    //Fetch from network and cache
+    var fetchFromNetwork = function(response) {
+        var cacheCopy = response.clone();
+        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            caches.open(version + 'pages').then(function(cache) {
+                cache.put(event.request, cacheCopy).then(function() {
+                    limitCache(cache, 25);
+                })
+            });
+        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+            caches.open(version + 'images').then(function(cache) {
+                cache.put(event.request, cacheCopy).then(function() {
+                    limitCache(cache, 10);
+                });
+            });
+        } else {
+            caches.open(version + 'assets').then(function add(cache) {
+                cache.put(event.request, cacheCopy);
+            });
+        }
+
+        return response;
+    }
+
+    //Fetch from network failed
+    var fallback = function() {
+        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            return caches.match(event.request).then(function (response) { 
+                return response || caches.match('/offline/');
+            })
+        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+            return new Response('<svg width="400" height="300" role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' }});
+        }
+    }
+
+    //This service worker won't touch non-get requests
+    if (event.request.method != 'GET') {
+        return;
+    }
+
+    //For HTML requests, look for file in network, then cache if network fails.
+    if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+            event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
+        return;
+        }
+
+    //For non-HTML requests, look for file in cache, then network if no cache exists.
+    event.respondWith(
+        caches.match(event.request).then(function(cached) {
+            return cached || fetch(event.request).then(fetchFromNetwork, fallback);
+        })
+    )
+});
+
+//After the install event
+self.addEventListener("activate", function(event) {
+    event.waitUntil(clearOldCaches())
+});
+
\ No newline at end of file diff --git a/content/blog/2015-11-15-fractions-js.md b/content/blog/2015-11-15-fractions-js.md new file mode 100644 index 0000000..9b0c42a --- /dev/null +++ b/content/blog/2015-11-15-fractions-js.md @@ -0,0 +1,126 @@ +--- +id: 398 +title: Math with Fractions.js +date: 2015-11-15T12:46:14+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=398 +permalink: /2015/11/fractions-js/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"dd3b15d9d3c9";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:68:"https://medium.com/@brandonrozek/math-with-fractions-js-dd3b15d9d3c9";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"dd3b15d9d3c9";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:68:"https://medium.com/@brandonrozek/math-with-fractions-js-dd3b15d9d3c9";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657739439" + - "135657739439" +kind: + - article +--- +Last week I published my first library over on Github called [Fractions.js](https://github.com/brandonrozek/Fractions.js). Fractions.js is a library to help avoid the [mathmatetical errors](http://floating-point-gui.de/) in floating point arithmetic. What do you mean by floating point artihmetic errors? Here is an example: .1 * .2 outputs 0.020000000000000004 even though the correct answer is .02 + + + +## Purpose {#purpose} + +My team and I are currently working on a new game for Math I/O. One of the levels is testing whether the player can add, subtract, multiply, and divide fractions correctly. I didn’t want to implement a solution where we check if the input entered is within a range of the answer. So I asked the team, how do you add, subtract, multiply, and divide fractions in your head? As we were working through it together, I realized that this is a common problem over at Math I/O. So I decided to make a library dedicated to this. + +## How it works {#how-it-works} + +I broke up each fraction into two things, a numerator and a denominator. With these two numbers, I can figure out all of the most common operations. + +### Addition {#addition} + +For addition, if two fractions have the same denominator, then you just need to add the numerators. + + 1/3 + 1/3 = 2/3 + + +If not, then you need to change it to have a common denominator. We can do this by multiply each fractions numerator and denominator by the other fractions denominator. + + 1/2 + 1/3 = (1 * 3)/ (2 * 3) + (1 * 2)/ (2 * 3) = 3/6 + 2/6 = 5/6 + + +### Subtraction {#subtraction} + +Works the same as addition, except the second fraction is subtracted (taken away) from the first. + +### Multiplication {#multiplication} + +To multiply two fractions, just multiply the numerators by each other, and the denominators by each other. + + 2/3 * 1/2 = 2/6 + + +### Division {#division} + +Treated similar to multiplication since dividing a number is the same thing as multiplying by it’s [reciprocal](https://www.mathsisfun.com/reciprocal.html). + + 1 / (1 / 2) = 1 * 2 = 2 + + +### Simplification {#simplification} + +Sometimes with the operations above, it’ll produce fractions in an unsimplified form. To avoid any confusion, I created a simplify function. It was challanging trying to figure out a way to code this. While I was browsing around for an implementation, I knocked into Euclider’s algorithm for finding the greatest common factor. Straight from the [Wikipedia article](https://en.wikipedia.org/wiki/Euclidean_algorithm) (where a is greater than b): + + + function gcd(a, b) + while b ≠ 0 + t := b; + b := a mod b; + a := t; + return a; + + +I can then simplify the fraction by dividing the numerator and denominator by the greatest common factor. + +## The API {#the-api} + +I decided to provide as much flexibility as I can in the API. You have several ways to create a new Fraction. + +

+var oneHalf = new Fraction(1,2);
+var oneHalf = new Fraction(.5);
+var oneHalf = new Fraction("1/2");
+var oneHalf = new Fraction("1", "2")
+
+ +All of these results will return a Fraction with a numerator of 1 and a denominator of 2. You also have two different ways to do the most common operations. + +

+var fiveThirds = Fraction.add("1/3", "4/3");
+var fiveThirds = new Fraction("1/3").add("4/3");
+
+ +The second style came from how jQuery implements it’s library. That way you can chain operations. + +

+new Fraction("1/2").add("2/3").divide("5/6").subtract("7/8").multiply("6/5").toString()
+
+ +Outputs '63/100' This is accomplished in the code through [prototypes](http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/). + +

+Fraction.add = function(frac1, frac2) {
+    Fraction.correctArgumentLength(2, arguments.length);
+    frac1 = Fraction.toFraction(frac1)
+    frac2 = Fraction.toFraction(frac2)
+
+    var newFrac = frac1;
+    newFrac.numerator = frac1.numerator * frac2.denominator + frac1.denominator * frac2.numerator;
+    newFrac.denominator = frac1.denominator * frac2.denominator;
+    return Fraction.simplify(newFrac);
+}
+Fraction.prototype.add = function(frac) {
+    Fraction.correctArgumentLength(1, arguments.length);
+    return Fraction.change(this, Fraction.add(this, frac));
+}
+
+ +In the code, the add prototype calls the Fraction.add function within it to avoid code duplication. + +## Conclusion {#conclusion} + +After I coded this up, I looked online for different implementations and found [fraction.js](https://github.com/ekg/fraction.js) by [Erik Garrison](http://hypervolu.me/~erik/). It’s important to look at different implementations and see which matches your needs better. This post isn’t meant to go fully into detail of the library. To know what else the library can do, visit the [readme page](https://github.com/brandonrozek/Fractions.js/blob/master/README.md). If you’re curious in how it’s implemented, check out the [code](https://github.com/brandonrozek/Fractions.js/blob/master/Fraction.js). [Email me](mailto:hello@brandonrozek.com) if you have any questions/criticisms 🙂 \ No newline at end of file diff --git a/content/blog/2015-11-30-limiting-cache-service-workers-revisited3.md b/content/blog/2015-11-30-limiting-cache-service-workers-revisited3.md new file mode 100644 index 0000000..1c6d513 --- /dev/null +++ b/content/blog/2015-11-30-limiting-cache-service-workers-revisited3.md @@ -0,0 +1,247 @@ +--- +id: 449 +title: Limiting the Cache in Service Workers Revisited +date: 2015-11-30T00:34:15+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=449 +permalink: /2015/11/limiting-cache-service-workers-revisited3/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"9cc502aae12e";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:93:"https://medium.com/@brandonrozek/limiting-the-cache-in-service-workers-revisited-9cc502aae12e";}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"9cc502aae12e";s:21:"follower_notification";s:2:"no";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:93:"https://medium.com/@brandonrozek/limiting-the-cache-in-service-workers-revisited-9cc502aae12e";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135657767639" + - "135657767639" +tumblr_crosspostr_crosspost: + - 'N' +kind: + - article +--- +Summary: I rewrote how cache limiting works to address a few problems listed later in this post. Check out the [gist](https://gist.github.com/brandonrozek/0cf038df40a913fda655) for the updated code. + + + +I wrote a function in my [previous service worker post](https://brandonrozek.com/2015/11/service-workers/) to help limit the cache. Here’s a reminder of what it looked like. + +

+var limitCache = function(cache, maxItems) {
+	cache.keys().then(function(items) {
+		if (items.length > maxItems) {
+			cache.delete(items[0]);
+		}
+	})
+}
+
+ +### The Problem + +Jeremy Keith updated the service worker on his site and noticed that the images has blown past the amount he allocated for it ([post](https://adactio.com/journal/9844)). Looking back at my service worker, I noticed that mine has the same shortcoming as well. So what happened? Service workers function in an asynchronous manner. Meaning it can be processing not just one, but many fetch events at the same time. This comes into conflict when there are synchronous instructions such as deleting the first item from the cache which Jeremy describes in his follow up [post](https://adactio.com/journal/9888). + +### A Solution + +Jeremy wrote a function to help trim the cache and asked when it would be appropriate to apply it. + +

+var trimCache = function (cacheName, maxItems) {
+    caches.open(cacheName)
+        .then(function (cache) {
+            cache.keys()
+                .then(function (keys) {
+                    if (keys.length > maxItems) {
+                        cache.delete(keys[0])
+                            .then(trimCache(cacheName, maxItems));
+                    }
+                });
+        });
+};
+
+ +And that got me thinking. In what situations is this problem more likely to occur? This particular problem happens when a lot of files are being called asynchronously. This problem doesn’t occur when only one file is being loaded. So when do we load a bunch of files? During page load. During page load, the browser might request css, javascript, images, etc. Which for most [websites](http://royal.pingdom.com/2011/11/21/web-pages-getting-bloated-here-is-why/), is a lot of files. Let’s now move our focus back to the humble script.js. Before, the only role it played with service workers was registering the script. However, if we can get the script to notify the service worker when the page is done loading, then the service worker will know when to trim the cache. + +

+if ('serviceWorker' in navigator) {
+	navigator.serviceWorker.register('https://yourwebsite.com/serviceworker.js', {scope: '/'});
+}
+window.addEventListener("load", function() {
+	if (navigator.serviceWorker.controller != null) {
+		navigator.serviceWorker.controller.postMessage({"command":"trimCache"});
+	}
+});
+
+ +Why if (navigator.serviceWorker.controller != null)? Service Workers don’t take control of the page immediately but on subsequent page loads, Jake Archibald [explains](https://jakearchibald.com/2014/using-serviceworker-today/). When the service worker does have control of the page however, we can use the [postMessage api](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) to send a message to the service worker. Inside, I provided a json with a “command” to “trimCache”. Since we send the json to the service worker, we need to make sure that it can receive it. + +

+self.addEventListener("message", function(event) {
+	var data = event.data;
+	
+	if (data.command == "trimCache") {
+		trimCache(version + "pages", 25);
+		trimCache(version + "images", 10);
+		trimCache(version + "assets", 30);
+	}
+});
+
+ +Once it receives the command, it goes on to trim all of the caches. + +### Conclusion + +So whenever you download a bunch of files, make sure to run navigator.serviceWorker.controller.postMessage({"command":"trimCache"}); on the main javascript file to trim the cache. A downside to this method is that since Service Workers don’t take control during the first page load, the cache isn’t trimmed until the second page load. If you can find a way to make it so that this event happens in the first page load [tell me](mailto:hello@brandonrozek.com) about it/write a blog post. 🙂 **Update:** To get the service worker to take control of the page immediately call [self.skipWaiting()](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting) after the install event and [self.clients.claim()](https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim) after the activate event. Current code for our humble service worker: + +

+var version = 'v2.0.24:';
+
+var offlineFundamentals = [
+	'/',
+	'/offline/'
+];
+
+//Add core website files to cache during serviceworker installation
+var updateStaticCache = function() {
+	return caches.open(version + 'fundamentals').then(function(cache) {
+		return Promise.all(offlineFundamentals.map(function(value) {
+			var request = new Request(value);
+			var url = new URL(request.url);
+			if (url.origin != location.origin) {
+				request = new Request(value, {mode: 'no-cors'});
+			}
+			return fetch(request).then(function(response) { 
+				var cachedCopy = response.clone();
+				return cache.put(request, cachedCopy); 
+				
+			});
+		}))
+	})
+};
+
+//Clear caches with a different version number
+var clearOldCaches = function() {
+	return caches.keys().then(function(keys) {
+			return Promise.all(
+          			keys
+            			.filter(function (key) {
+              				return key.indexOf(version) != 0;
+            			})
+            			.map(function (key) {
+              				return caches.delete(key);
+            			})
+        		);
+		})
+}
+
+/*
+	trims the cache
+	If cache has more than maxItems then it removes the excess items starting from the beginning
+*/
+var trimCache = function (cacheName, maxItems) {
+    caches.open(cacheName)
+        .then(function (cache) {
+            cache.keys()
+                .then(function (keys) {
+                    if (keys.length > maxItems) {
+                        cache.delete(keys[0])
+                            .then(trimCache(cacheName, maxItems));
+                    }
+                });
+        });
+};
+
+
+//When the service worker is first added to a computer
+self.addEventListener("install", function(event) {
+	event.waitUntil(updateStaticCache()
+				.then(function() { 
+					return self.skipWaiting(); 
+				})
+			);
+})
+
+self.addEventListener("message", function(event) {
+	var data = event.data;
+	
+	//Send this command whenever many files are downloaded (ex: a page load)
+	if (data.command == "trimCache") {
+		trimCache(version + "pages", 25);
+		trimCache(version + "images", 10);
+		trimCache(version + "assets", 30);
+	}
+});
+
+//Service worker handles networking
+self.addEventListener("fetch", function(event) {
+
+	//Fetch from network and cache
+	var fetchFromNetwork = function(response) {
+		var cacheCopy = response.clone();
+		if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+			caches.open(version + 'pages').then(function(cache) {
+				cache.put(event.request, cacheCopy);
+			});
+		} else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+			caches.open(version + 'images').then(function(cache) {
+				cache.put(event.request, cacheCopy);
+			});
+		} else {
+			caches.open(version + 'assets').then(function add(cache) {
+				cache.put(event.request, cacheCopy);
+			});
+		}
+
+		return response;
+	}
+
+	//Fetch from network failed
+	var fallback = function() {
+		if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+			return caches.match(event.request).then(function (response) { 
+				return response || caches.match('/offline/');
+			})
+		} else if (event.request.headers.get('Accept').indexOf('image') != -1) {
+			return new Response('Offlineoffline', { headers: { 'Content-Type': 'image/svg+xml' }});
+		} 
+	}
+	
+	//This service worker won't touch non-get requests
+	if (event.request.method != 'GET') {
+		return;
+	}
+	
+	//For HTML requests, look for file in network, then cache if network fails.
+	if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
+        	event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
+		return;
+    	}
+
+	//For non-HTML requests, look for file in cache, then network if no cache exists.
+	event.respondWith(
+		caches.match(event.request).then(function(cached) {
+			return cached || fetch(event.request).then(fetchFromNetwork, fallback);
+		})
+	)	
+});
+
+//After the install event
+self.addEventListener("activate", function(event) {
+	event.waitUntil(clearOldCaches()
+				.then(function() { 
+					return self.clients.claim(); 
+				})
+			);
+});
+
+ +

+if ('serviceWorker' in navigator) {
+	navigator.serviceWorker.register('https://brandonrozek.com/serviceworker.js', {scope: '/'});
+}
+window.addEventListener("load", function() {
+	if (navigator.serviceWorker.controller != null) {
+		navigator.serviceWorker.controller.postMessage({"command":"trimCache"});
+	}
+});
+
\ No newline at end of file diff --git a/content/blog/2015-12-22-playing-with-qr-codes.md b/content/blog/2015-12-22-playing-with-qr-codes.md new file mode 100644 index 0000000..97075ec --- /dev/null +++ b/content/blog/2015-12-22-playing-with-qr-codes.md @@ -0,0 +1,48 @@ +--- +id: 572 +title: Playing with QR Codes +date: 2015-12-22T15:13:44+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=572 +permalink: /2015/12/playing-with-qr-codes/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "135727537264" + - "135727537264" +bridgy_syndication: + - | + + https://twitter.com/B_RozekJournal/status/790337750280970241 +kind: + - article +--- +Looking at Aaron Parecki’s [“Fun with QR Codes”](https://aaronparecki.com/articles/2015/10/05/1/fun-with-qr-codes) inspired me to play with QR Codes myself. Using the tool [QArt Coder](http://research.swtch.com/qr/draw) made by [Russ Cox](https://plus.google.com/116810148281701144465), I made a QR Code with my face in it! + + + +qrcode-large + +### Why QR Codes? + +QR Codes aren’t prevalent in the United States of America. In fact, they’re often viewed by technologists as a [joke](http://picturesofpeoplescanningqrcodes.tumblr.com/). But as [Christina Xu](http://www.christinaxu.org/) points out on her Medium post [“Pictures of Chinese People Scanning QR Codes”](https://medium.com/chrysaora-weekly/pictures-of-chinese-people-scanning-qr-codes-a564047ec58f), it’s not a joke everywhere. In fact, many people actually depend on this humble little QR code to get by in their day. Another story, my family and I go out to eat sometimes. Occasionally, we’ll knock into a Heinz Ketchup bottle. + +
+ Picture of Heinz ketchup bottle with QR Code. + +

+ Picture by Azad Zahoory +

+
My brother would get so excited whenever he saw this. This little ketchup bottle meant that we got to play a + +trivia game. No matter what you think of QR Codes, vanity or not, there are people who use it every day. So have some fun and make yourself a QR Code of your own. You know, just in case 😉 + +### Setting up the QR Code + +First, you need a picture. I used a picture of myself. Then for the QArt Coder site to work correctly, the image needs to be in high-contrast. Meaning, it needs to be mostly black and white. To accomplish this, fire up [Gimp](https://www.gimp.org/) (or your image editor of choice), and hit Color -> Threshold. That will give you a black and white version of the picture where you can then play around with the slider to get it just how you want it. After that, open up [QArt Coder](http://research.swtch.com/qr/draw) and upload the image onto the site. Once that’s accomplished, you might need to play with the QR Size, Image Size, Rotation, and other options. After that, hit “Save this QR Code” and viola! You got yourself three different sizes of QR codes to use. What should you do with the QR Code after you get it? First, brag to your friends about how cool it looks. Then maybe put it on your [business card](https://www.webdesignerdepot.com/2011/07/30-creative-qr-code-business-cards/). If you can think of any other excuses uses of QR Codes [contact me](mailto:hello@brandonrozek.com) 🙂 \ No newline at end of file diff --git a/content/blog/2015-12-27-creating-vcards-from-h-cards.md b/content/blog/2015-12-27-creating-vcards-from-h-cards.md new file mode 100644 index 0000000..cde20c2 --- /dev/null +++ b/content/blog/2015-12-27-creating-vcards-from-h-cards.md @@ -0,0 +1,324 @@ +--- +id: 599 +title: Creating vCards from h-cards +date: 2015-12-27T15:17:12+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=599 +permalink: /2015/12/creating-vcards-from-h-cards/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:74:"https://cdn-images-1.medium.com/fit/c/200/200/1*dmbNkD5D-u45r44go_cf0g.png";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"9eab6bd8e0e4";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:74:"https://medium.com/@brandonrozek/creating-vcards-from-h-cards-9eab6bd8e0e4";}' +mf2_cite: + - 'a:1:{s:6:"author";a:0:{}}' +tumblr_post_id: + - "136059699334" +kind: + - article +--- +Microformats is semantic HTML used to convey metadata. Using an userscript, I can generate a vCard from the representative h-card of the page. The code for this is on this gist [here.](https://gist.github.com/brandonrozek/e0153b2733e947fa9c87) + + + +### Terminology + +[Microformats](http://microformats.org/wiki/Main_Page) allows search engines, browsers, websites, or people like me to consume content on a site. + +[H-card](http://microformats.org/wiki/h-card) is a type of microformat that serves as a contact card for people and organizations. + +[vCard](https://en.wikipedia.org/wiki/VCard) is the standard for electronic business cards. They’re most likely used in your phone to store contacts. + +Userscript is essentially JavaScript that runs in the [Greasemonkey](http://www.greasespot.net/) extension. + +### What I’ll need + + * Microformat parser + * Way to find the representative h-card + * Way to generate a vCard from an h-card + * The userscript itself + +### Implementation + +To keep everything in small [reusable components](https://en.wikipedia.org/wiki/Modular_programming), I created four different sections. Thankfully, [Glenn Jones](http://glennjones.net/) already wrote a JavaScript microformats parser called [microformat-shiv.](https://github.com/glennjones/microformat-shiv) It’s licensed with [MIT](https://tldrlegal.com/license/mit-license), so we can use it, yay! + +Next, I need to find the representative h-card of the page. Following the [instructions](http://microformats.org/wiki/representative-h-card-parsing) on the microformats wiki, I wrote the following code. + +

+/*
+   representative-h-card - v0.1.0
+   Copyright (c) 2015 Brandon Rozek
+   Licensed MIT 
+*/
+
+/**
+	Finds the representative h-card of the page
+	[http://microformats.org/wiki/representative-h-card-parsing]
+	@returns representative h-card if found, null otherwise
+**/
+var representativeHCard = function(hCards, url) {
+	if (hCards.items.length == 0) {
+		return null;
+	} else if (hCards.items.length == 1 && urlsMatchURL(hCards.items[0], url)) {
+		hCard = hCards;
+		hCard.items = [hCards.items[0]];
+		return hCard
+	} else {
+		for (var i = 0; i < hCards.items.length; i++) {
+			if (urlsMatchURL(hCards.items[i], url) && (uidsMatchURL(hCards.items[i], url) || relMeMatchURL(hCards, url))) {
+				hCard = hCards;
+				hCard.items = [hCards.items[i]];
+				return hCard
+			}
+
+		}
+	}
+	return null;
+}
+
+var urlsMatchURL = function(hCard, url) {
+	var urls = hCard.properties.url;
+	if (typeof(urls) == "object") {
+		for (var i = 0; i < urls.length; i++) {
+			if (new URL(urls[i]).toString() == new URL(url).toString()) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+var uidsMatchURL = function(hCard, url) {
+	var uids = hCard.properties.uid;
+	if (typeof(uids) == "object") {
+		for (var i = 0; i < uids.length; i++) {
+			if (new URL(uids[i]).toString() == new URL(url).toString()) {
+				return true;
+			}
+		}
+	}
+	return false;
+};
+var relMeMatchURL = function(microformats, url) {
+	var me = microformats.rels.me;
+	if (typeof(me) == "object") {
+		for (var i = 0; i < me.length; i++) {
+			if (new URL(me[i]).toString() == new URL(url).toString()) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+ +Next up, is making the vCard. For this, I had to look at the [vCard 4.0 specification](https://tools.ietf.org/html/rfc6350) to figure out what the property names and values are. Then I browsed around different sites (takes you to a random [Indieweb](https://indiewebcamp.com/) site)  to figure out which properties are the most common. + +The properties I ended up adding to the vCard. + + * name + * photo + * telephone numbers + * URLs + * [IMPPs](https://en.wikipedia.org/wiki/Instant_Messaging_and_Presence_Protocol) (Instant Messaging and Presence Protocol) + * emails + * roles + * categories + * notes + + As I was browsing around, I noticed that a few people would have empty values for certain properties on their h-card. To avoid having this show up on the vCard, I added a filter that takes out empty strings. + +

+/*
+   vCard-from-h-card - v0.1.0
+   Copyright (c) 2015 Brandon Rozek
+   Licensed MIT 
+*/
+var makeVCard = function(hCard) {
+	var vCard = "BEGIN:VCARDnVERSION:4.0n";
+
+	//Add full name
+	var name = hCard.items[0].properties.name;
+	if (typeof(name) == "object") {
+		name.removeEmptyStrings();
+		for (var i = 0; i < name.length; i++) {
+			vCard += "FN: " + name[i] + "n";
+		}
+	}
+
+	//Add photo
+	var photo = hCard.items[0].properties.photo;
+	if (typeof(photo) == "object") {
+		photo.removeEmptyStrings();
+		for (var i = 0; i < photo.length; i++) {
+			vCard += "PHOTO: " + photo[i] + "n";
+		}
+	}
+
+	//Add phone number
+	var tel = hCard.items[0].properties.tel;
+	if (typeof(tel) == "object") {
+		tel.removeEmptyStrings();
+		for (var i = 0; i < tel.length; i++) {
+			try {
+				if (new URL(tel[i]).schema == "sms:") {
+					vCard += "TEL;TYPE=text;VALUE=text: " + new URL(tel[i]).pathname + "n";
+				} else {
+					vCard += "TEL;TYPE=voice;VALUE=text: " + new URL(tel[i]).pathname + "n";
+				}
+			} catch(e) {
+				vCard += "TEL;TYPE=voice;VALUE=text: " + tel[i] + "n";
+			}
+		}
+	}
+
+	//Add URLs
+	var url = hCard.items[0].properties.url;
+	if (typeof(url) == "object") {
+		url.removeEmptyStrings();
+		for (var i = 0; i < url.length; i++) {
+			vCard += "URL: " + url[i] + "n";
+		}
+	}
+
+	var impp = hCard.items[0].properties.impp;
+	//Add IMPP (Instant Messaging and Presence Protocol)
+	if (typeof(impp) == "object") {
+		impp.removeEmptyStrings();
+		for (var i = 0; i < impp.length; i++) {
+			vCard += "IMPP;PREF=" + (i + 1) + ": " + impp[i] + "n";
+		}
+	}
+
+	//Add emails
+	var email = hCard.items[0].properties.email;
+	if (typeof(email) == "object") {
+		email.removeEmptyStrings();
+		for (var i = 0; i < email.length; i++) {
+			try {
+				vCard += "EMAIL: " + new URL(email[i]).pathname + "n";
+			} catch (e) { 
+				vCard += "EMAIL: " + email[i] + "n" 
+			}		
+		}
+	}
+
+	//Add roles
+	var role = hCard.items[0].properties.role;
+	if (typeof(role) == "object") {
+		role.removeEmptyStrings();
+		for (var i = 0; i < role.length; i++) {
+			vCard += "ROLE: " + role[i] + "n";
+		}
+	}
+
+	//Add Organizations
+	var org = hCard.items[0].properties.org;
+	if (typeof(org) == "object") {
+		org.removeEmptyStrings();
+		for (var i = 0; i < org.length; i++) {
+			vCard += "ORG: " + org[i] + "n";
+		}
+	}
+
+	//Add Categories
+	var category = hCard.items[0].properties.category; 
+	if (typeof(category) == "object") {
+		vCard += "CATEGORIES: " + category.removeEmptyStrings().join(",") + "n";
+	}
+
+	//Add notes
+	var note = hCard.items[0].properties.note;
+	if (typeof(note) == "object") {
+		note.removeEmptyStrings();
+		for (var i = 0; i < note.length; i++) {
+			vCard += "NOTE: " + note[i] + "n";
+		}
+	}
+
+	return vCard + "END:VCARD";
+	
+}
+
+Array.prototype.removeEmptyStrings = function() {
+	return this.filter(function(i) { return i !== "" })
+}
+
+
+ +Now for the final part, making the userscript. Inspired by [Ryan Barret](https://snarfed.org/) and his userscript [Let’s Talk,](https://github.com/snarfed/misc/blob/master/userscripts/lets_talk.user.js) this userscript brings all of the above modules together. First it grabs the microformats from the page using microformat-shiv. + +For some reason, when I tried filtering it by ‘h-card’ it froze my computer. So I wrote my own little filter instead. + +After I grab the representative h-card from the page using the little module I wrote, I generated a vCard. With the vCard generated, I set up a little HTML and CSS to display the link in the top left corner of the screen. + +The link is actually a [data uri](https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs) that has all of the information of the vCard encoded in it. Depending on your browser, once you click the link you might have to hit CTRL-S to save. + +

+/*
+   show-vCard - v0.1.0
+   Copyright (c) 2015 Brandon Rozek
+   Licensed MIT 
+*/
+var filterMicroformats = function(items, filter) {
+	var newItems = [];
+	for (var i = 0; i < items.items.length; i++) {
+		for (var k = 0; k < items.items[i].type.length; k++) {
+			if (filter.indexOf(items.items[i].type[k]) != -1) {
+				newItems.push(items.items[i]);
+			}
+		}
+	}
+	items.items = newItems;
+	return items;
+}
+var render = function() {
+	var hCards = filterMicroformats(Microformats.get(), ['h-card']);
+	var person = representativeHCard(hCards, location.origin);
+	if (person == null) {
+		return;
+	}
+
+	var node = document.createElement("div");
+	node.setAttribute("class", "lt");
+	
+	var link = "<a href="text/vcf;base64," + btoa(makeVCard(person))+ "" target="_blank">vCard</a>";
+	var style = " 
+			.lt { 
+				position: absolute; 
+				left: 24px; 
+				top: 0; 
+				color: #DDD; 
+				background-color: #FFD700; 
+				z-index: 9999; 
+				border-width: medium 1px 1px; 
+				border-style: none solid solid; 
+				border-color: #DDD #C7A900 #9E8600; 
+				box-shadow: 0px 1px rgba(0, 0, 0, 0.1), 0px 1px 2px rgba(0, 0, 0, 0.1), 0px 1px rgba(255, 255, 255, 0.34) inset; 
+				border-radius: 0px 0px 4px 4px; 
+		        } 
+			.lt a { 
+				padding: .5rem; 
+			 	color: #8f6900; 
+			 	text-shadow: 0px 1px #FFE770; 
+				border: medium none; 
+			} 
+		     ";
+
+	node.innerHTML = link + style;
+	document.body.appendChild(node);	
+}
+document.addEventListener("DOMContentLoaded", function() {
+	render();
+});
+
+ +Sadly, I have no way of controlling the file name when you save it so you’ll have to manually rename it to something more meaningful than a random string of characters. Also remember to add the extension ‘.vcf’ for it to be recognized by some devices. + +### Conclusion + +Fire up your favorite userscript handling tool and add the [script](https://gist.github.com/brandonrozek/e0153b2733e947fa9c87) in! Of course, since it’s pure JavaScript, you can also add it to your own site to serve the same purpose. + +I ran into a small problem loading a contact onto my Android 5.0.2 phone. Apparently, they don’t support vCard 4.0 yet so I had to go into the file and change the line that says “VERSION 4.0” to “VERSION 3.0” which then allowed me to import the file into my contacts. + +As with all the code I write, feel free to comment/criticize. I love hearing feedback so if you spot anything, [contact me](mailto:hello@brandonrozek.com) 🙂 + +Also posted on [IndieNews](http://news.indiewebcamp.com/en){.u-syndication} \ No newline at end of file diff --git a/content/blog/2016-08-16-pass-password-manager.md b/content/blog/2016-08-16-pass-password-manager.md new file mode 100644 index 0000000..d3e8afb --- /dev/null +++ b/content/blog/2016-08-16-pass-password-manager.md @@ -0,0 +1,94 @@ +--- +id: 919 +title: Pass the password manager +date: 2016-08-16T23:37:09+00:00 +author: Brandon Rozek +layout: post +guid: http://brandonrozek.com/?p=919 +permalink: /2016/08/pass-password-manager/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";N;s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:4:"none";s:3:"url";N;}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "149056904199" +bridgy_syndication: + - https://twitter.com/B_RozekJournal/status/790336614866100224 +tumblr_crosspostr_crosspost: + - 'N' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +kind: + - note +--- +Looking over the list of programs installed on my computer, one of my all time favorites is a program called [Pass](https://www.passwordstore.org/). It’s a program available under most Linux distributions, Mac OS X (through [Brew](http://brew.sh/)), [Windows](https://github.com/mbos/Pass4Win), [Android](https://play.google.com/store/apps/details?id=com.zeapo.pwdstore), and [iOS](https://github.com/davidjb/pass-ios#readme). It stores all of the passwords using gpg encryption and stores them as actual files on the hard disk. Meaning if you wanted, you can sync them to all your devices! + +This program assumes a light familiarity with the terminal + + + +## Setup {#setup} + +First if you do not already have a gpg key, [create one](http://wooledge.org/~greg/crypto/node41.html). + +Then in the terminal type in + + pass init youremail@address + +Substituting youremail@address with the email associated with your gpg key. + +This will autmatically create an empty repository under your home folder in a folder labeled `.pass` + +If you are switching from an existing password manager, check to see if on the [Pass homepage](https://www.passwordstore.org/), there doesn’t exist a script to help you out + +## Basic Tasks {#basic-tasks} + +To insert a password into pass + + pass insert password-name + +It will then prompt you to enter the password + +To show passwords you have already inserted + + pass + +To show an individual password + + pass password-name + +But generally I find it handy to have it automatically in my clipboard. You can do that with the -c option + + pass -c password-name + +You can generate new secure passwords using pass. (-c copies the result into your clipboard) + + pass generate -c password-name password-length + +If you don’t want it to output symbols, use the -n option to restrict it to alphanumericals + + pass generate -n -c password-name password-length + +Another command i find handy is the `find` command. Mainly because I have over a 100 passwords in this system and i tend to forget what I named some of them + + pass find search-string + +There are too many commands to list them all, but if you ever want to find out more, check out the manual entry page for `pass` + + man pass + +## Extra: Syncing {#sync} + +I use a nextCloud instance on my server to sync my passwords, but I don’t see a reason why this wouldn’t work with other projects like dropbox, syncthing, or any other sync solution + +Some sync solutions don’t like to sync folders that begin with a ‘.’, my solution around this is to create a symbolic link between that and a folder you wish to link it to + + ln -s /path/to/home/folder/.password-store /path/to/sync/folder/password-store + +Then you just need to make sure to make the same link to all your other computers + +## Conclusion {#conclusion} + +I like Pass for it’s ease of use and for the fact that I’m not tied into any one company for managing my passwords. It’s based on open source tools and the fact I didn’t have to configure a database is a huge plus for me + +If you’re in a need of a password manager (I hope you have more than one password), then give pass a shot. It served me and my many passwords well. \ No newline at end of file diff --git a/content/blog/2017-03-07-knit-document-rstudio.md b/content/blog/2017-03-07-knit-document-rstudio.md new file mode 100644 index 0000000..c96e42d --- /dev/null +++ b/content/blog/2017-03-07-knit-document-rstudio.md @@ -0,0 +1,29 @@ +--- +id: 2090 +title: Knit a Document in RStudio +date: 2017-03-07T04:29:50+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2090 +permalink: /2017/03/knit-document-rstudio/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "158095811719" +format: aside +kind: + - note +--- +In case you were wondering how I got all the R code and output for the [“Do females live longer than males?”](https://brandonrozek.com/portfolio/male-vs-female-life-expectancy/) page. There is actually a function in RStudio that allows one to compile a report based on code and it’s output. + + + +First go to File->Knit Document. If this is your first time, then it will install RMarkdown, a dependency this tool needs to compile the report. + +Once that is downloaded, it will let you choose between three different file formats (HTML, PDF, MS Word). For the purposes of blog posts, I like to output it in HTML so I can copy and paste the code. But for personal use, I like using PDFs + +After you select the file format, hit compile, and voila! A nice neat compiled report is created for you. Here is a [pdf](https://brandonrozek.com/wp-content/uploads/2017/03/LifeExpectancy.pdf) example of the report I made. \ No newline at end of file diff --git a/content/blog/2017-03-07-uniformity-math-random.md b/content/blog/2017-03-07-uniformity-math-random.md new file mode 100644 index 0000000..ea76278 --- /dev/null +++ b/content/blog/2017-03-07-uniformity-math-random.md @@ -0,0 +1,132 @@ +--- +id: 2095 +title: Uniformity of Math.random() +date: 2017-03-07T21:50:52+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2095 +permalink: /2017/03/uniformity-math-random/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "158123669889" +format: aside +kind: + - note +--- +There are many cases where websites use random number generators to influence some sort of page behavior. One test to ensure the quality of a random number generator is to see if after many cases, the numbers produced follow a uniform distribution. + + + +Today, I will compare Internet Explorer 11, Chrome, and Firefox on a Windows 7 machine and report my results. + +## Hypothesis + +H0: The random numbers outputted follow the uniform distribution + +HA: The random numbers outputted do not follow the uniform distribution + +## Gathering Data + +I wrote a small [website](http://share.zeropointshift.com/files/2017/03/random.html) and obtained my data by getting the CSV outputted when I use IE11, Firefox, and Chrome. + +The website works by producing a random number using Math.random() between 1 and 1000 inclusive and calls the function 1,000,000 times. Storing it’s results in a file + +This website produces a file with all the numbers separated by a comma. We want these commas to be replaced by newlines. To do so, we can run a simple command in the terminal + +

+grep -oE '[0-9]+' Random.csv > Random_corrected.csv
+
+ +Do this with all three files and make sure to keep track of which is which. + +Here are a copy of my files for [Firefox](https://brandonrozek.com/wp-content/uploads/2017/03/Firefox_corrected.csv), [Chrome](https://brandonrozek.com/wp-content/uploads/2017/03/Chrome_corrected-1.csv), and [IE11](https://brandonrozek.com/wp-content/uploads/2017/03/IE11_corrected.csv) + +## Check Conditions + +Since we’re interested in if the random values occur uniformly, we need to perform a Chi-Square test for Goodness of Fit. With every test comes some assumptions + +Counted Data Condition: The data can be converted from quantatative to count data. + +Independence Assumption: One random value does not affect another. + +Expected Cell Frequency Condition: The expected counts are going to be 10000 + +Since all of the conditions are met, we can use the Chi-square test of Goodness of Fit + +## Descriptive Statistics + +For the rest of the article, we will use R for analysis. Looking at the histograms for the three browsers below. The random numbers all appear to occur uniformly + +
rm(list=ls())
+chrome = read.csv("~/Chrome_corrected.csv", header = F)
+firefox = read.csv("~/Firefox_corrected.csv", header = F)
+ie11 = read.csv("~/IE11_corrected.csv", header = F)
+
+ +

+hist(ie11$V1, main = "Distribution of Random Values for IE11", xlab = "Random Value")
+ +![](https://brandonrozek.com/wp-content/uploads/2017/03/ie11hist.png) + +
hist(firefox$V1, main = "Distribution of Random Values for Firefox", xlab = "Random Value")
+ +![](https://brandonrozek.com/wp-content/uploads/2017/03/firefoxhist.png) + +
hist(chrome$V1, main = "Distribution of Random Values for Chrome", xlab = "Random Value")
+ +![](https://brandonrozek.com/wp-content/uploads/2017/03/chromehist.png) + +## Chi-Square Test + +Before we run our test, we need to convert the quantatative data to count data by using the plyr package + +
#Transform to count data
+library(plyr)
+chrome_count = count(chrome)
+firefox_count = count(firefox)
+ie11_count = count(ie11)
+
+ +Run the tests + +

+# Chi-Square Test for Goodness-of-Fit
+chrome_test = chisq.test(chrome_count$freq)
+firefox_test = chisq.test(firefox_count$freq)
+ie11_test = chisq.test(ie11_count$freq)
+
+# Test results
+chrome_test
+ +As you can see in the test results below, we fail to reject the null hypothesis at a 5% significance level because all of the p-values are above 0.05. + + ## + ## Chi-squared test for given probabilities + ## + ## data: chrome_count$freq + ## X-squared = 101.67, df = 99, p-value = 0.4069 + +
firefox_test
+ + ## + ## Chi-squared test for given probabilities + ## + ## data: firefox_count$freq + ## X-squared = 105.15, df = 99, p-value = 0.3172 + +
ie11_test
+ + ## + ## Chi-squared test for given probabilities + ## + ## data: ie11_count$freq + ## X-squared = 78.285, df = 99, p-value = 0.9384 + +## Conclusion + +At a 5% significance level, we fail to obtain enough evidence to suggest that the distribution of random number is not uniform. This is a good thing since it shows us that our random number generators give all numbers an equal chance of being represented. We can use Math.random() with ease of mind. \ No newline at end of file diff --git a/content/blog/2017-03-09-simplifying-expressions-octave.md b/content/blog/2017-03-09-simplifying-expressions-octave.md new file mode 100644 index 0000000..72250f5 --- /dev/null +++ b/content/blog/2017-03-09-simplifying-expressions-octave.md @@ -0,0 +1,59 @@ +--- +id: 2115 +title: Simplifying Expressions with Octave +date: 2017-03-09T02:09:58+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2115 +permalink: /2017/03/simplifying-expressions-octave/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:22:"bridgy-publish_twitter";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "158172999969" +mf2_syndication: + - 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/839659534146801665";}' +format: aside +kind: + - note +--- +Octave is a high level programming language intended for numerical computations. One of the cool features of this is that with symbolic expressions, you can then simplify mathematical expressions. + + + +## Setup + +First install [Octave](https://www.gnu.org/software/octave/) and the [symbolic package](https://octave.sourceforge.io/symbolic/) using the website or your package manager of choice. + +Then in octave type in the following code + + + pkg load symbolic + + +## Usage + +For every variable not defined earlier in your expression, make sure to declare it as a symbolic data type + +
syms x y
+ +Then make an expression + +

+expr = y + sin(x)^2 + cos(x)^2
+
+ +You can then ask Octave to simplify the expression for you + +

+simp_expr = simplify(expr)
+
+ +Displaying it shows it as + +
(sym) y + 1
+ +Which is indeed a simplification using a trig identity 🙂 \ No newline at end of file diff --git a/content/blog/2017-03-14-monte-carlo-pi.md b/content/blog/2017-03-14-monte-carlo-pi.md new file mode 100644 index 0000000..1dcf5b2 --- /dev/null +++ b/content/blog/2017-03-14-monte-carlo-pi.md @@ -0,0 +1,125 @@ +--- +id: 2089 +title: Monte Carlo Pi +date: 2017-03-14T05:31:21+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2089 +permalink: /2017/03/monte-carlo-pi/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +tumblr_post_id: + - "158383170019" +mf2_syndicate-to: + - 'a:1:{i:0;s:22:"bridgy-publish_twitter";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +mf2_syndication: + - 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/841522141346570244";}' +format: aside +kind: + - note +--- +Using Monte Carlo methods, we can create a simulation that approximates pi. In this post, we will go over the math behind the approximation and the code. + + + +## The Math + +Pi is a mathematical constant consisting of the ratio between the circumfrence of a circle and it’s diameter. + +The circumfrence of the circle is defined to be $$ C = 2\pi r$$ while the diameter of the circle is $$d = 2r$$ + +Take the ratio between the two and you get $$\frac{2\pi r}{2r} = \pi$$ + +Now let us consider the area of a circle. One can derive the area of a circle by taking the integral of the circumfrence with respect to it’s radius $$ A_{circle} = \int{(2\pi r) dr} = \pi r^2 $$ + +Let us simplify the formula more by setting the radius equal to one. $$A_{circle} = \pi$$ + +Now consider only the first quadrant of the circle. Since our circle is centered at the origin and all the points on the circumfrence is equidistant from the center, our area is now $$A_{circle} = \frac{1}{4} \pi$$ + +And bound the quarter-circle in a 1×1 box with an area of $$A_{square} = 1^2 = 1$$ + +Notice that the ratio between the circle and the square is a quarter of pi $$\frac{A\_{circle}}{A\_{square}} = \frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$ + +## Simulation and Statisitcs + +The formula for a circle centered at the origin with radius one is $$x^2 + y^2 = 1$$ + +Let us focus again on the first quadrent, and do a Monte Carlo simulation to find the area of the quarter-circle + +![](https://brandonrozek.com/wp-content/uploads/2017/03/circlefilled.png) + +We can do this by what is called the dart board method. We generate a random x and y between 0 and 1. If it satisfies the inequality $$x^2 + y^2 \leq 1$$ then it counts as being inside the circle, if not then it lies outside the circle. + +That point will count as an really small area. The point will always be inside the square but may sometimes be inside the circle. Running the simulations a large number of times allows us to add up all the tiny little areas that make up the circle and the square. + +To add up these small areas we need to make an assumption. The assumption is that the variance of all the little Monte Carlo trials are the same. Since we are using a psuedo-random number generator, it is safe to assume it is met. + +This will allow us to perform a pooled empiricle probability on the simulations to sum up the areas. + +Meaning the area of the circle will be the number of times that the inequality was satisfied $$A_{circle} = \# Successes$$ + +And the area of the square will be the number of times the simulation was run, since the random numbers generated will always be between 0 and 1 $$A_{square} = \# Trials$$ + +Recall that taking the ratio of the area of the circle and the area of the square is a fourth of pi. $$\frac{\frac{1}{4} \pi}{1} = \frac{1}{4} \pi$$ + +Multiply this number by 4 and you get the value for pi. + +This tells us that four times the probability that the randomly generated point is in the circle is equal to pi. + +$$\pi = 4 \* (Probability\ of\ being\ inside\ circle) = 4 \* \frac{\# Success}{\# Trials} = 4 * \frac{A\_{circle}}{A\_{square}}$$ + +## Implementation + +For the Monte Carlo simulation I used Java. The BigDecimal implementation was used so that there wouldn’t be any issue with integer size limits + +
/** Calculates Pi
+  * @author Brandon Rozek
+*/
+// Big Integers are used so we don't run into the integer size limit
+import java.math.BigInteger;
+import java.math.BigDecimal;
+class MonteCarloPi {
+        public static void main(String[] args) {
+
+                BigInteger successes = BigInteger.ZERO;
+                BigInteger trials = BigInteger.ZERO;
+
+ +For this simulation, we will run 1,000,000,000 trials + +
 BigInteger numTrials = new BigInteger("1000000000");
+/*
+    Monte Carlo Simulation
+        Generate a random point 0 <= x < 1 and 0 <= y < 1
+        If the generated point satisfies x^2 + x^2 < 1
+           Count as a success
+        Keep track of the number of trials and successes
+*/
+for (; trials.compareTo(numTrials) < 0; trials = trials.add(BigInteger.ONE)) {
+    double randomX = Math.random();
+    double randomY = Math.random();
+    if (Math.pow(randomX, 2) + Math.pow(randomY, 2) < 1) {
+        successes = successes.add(BigInteger.ONE);
+    }
+}
+
+ +And then we finalize it with a quick calculation of pi + +
// (Number of successes) / (Number of trials) * 4 gives the approximation for pi
+BigDecimal pi = new BigDecimal(successes)
+                       .divide(new BigDecimal(trials))
+                       .multiply(new BigDecimal("4"));
+System.out.println("The calculated value of pi is: " + pi);
+}}
+
+ +## Conclusion + +We found an approximation of pi using the Monte Carlo methods! I find that really awesome, however, there are some concerns I have with this approach. + +1) We don’t keep track of double counting. One possible solution for this is increasing the radius and bounding box appropriately so that the probability of double counting is low. + +2) Speed. The more trials you ask it to run, the longer it takes to perform all of the simulations. One possible way around this is to write a parrallel version of this code. That’s possible because of the equal variance that we spoke of earlier. Pooling the successses and trials will still result in a good approximation. \ No newline at end of file diff --git a/content/blog/2017-05-24-viewing-java-applets.md b/content/blog/2017-05-24-viewing-java-applets.md new file mode 100644 index 0000000..7dbe207 --- /dev/null +++ b/content/blog/2017-05-24-viewing-java-applets.md @@ -0,0 +1,74 @@ +--- +id: 2174 +title: Viewing Java Applets +date: 2017-05-24T15:59:45+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2174 +permalink: /2017/05/viewing-java-applets/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:22:"bridgy-publish_twitter";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "161024360884" +mf2_syndication: + - 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/867409810932760576";}' +kind: + - article +--- +When you use an IDE there are many things you can take for granted. A section of an intro level computer science course at my university uses [JGrasp](http://www.jgrasp.org/) to build Java Applets. + +Following around using a normal text editor, I found that I couldn’t just compile and run the code like I have with my java programs in the past. To be able to help around and assist in the course, I need to be able to build and run these applications. The rest of this article describes the process I underwent to be able to use my existing setup to write and build java applets. Of course you can always install JGrasp and have that all built in, but it’s always nice to not have to change your workflow. + + + +When I tried following along, I would receive the following error + + Main method not found in class HelloWorld, please define main method as... + +Which makes sense since I have never defined a main method inside my source code. So how do I go about doing this? + +## Setup + +Java Applets are meant to run on web pages, because of this one needs an html file to host the applet. The following code gives you the bare minimum for setting up the html file. I called it `HelloWorld.html`. + +

+<html>
+    <head><title>Applet Container<title>
+    <body>
+        <applet code='HelloWorld.class' width=400 height=400></applet>
+    </body>
+</html>
+
+ +## Hello World Program + +To get it up and running, I will show a “Hello World” like application for applets. + +

+import javax.swing.JApplet;
+import java.awt.Graphics;
+
+public class HelloWorld extends JApplet {
+    public void paint(Graphics g) {
+        g.drawString("Hello World", 30, 30);
+    }
+} 
+
+ +## Running the Applet + +Now we need to compile the code + +
javac HelloWorld.java
+ +Then run the appletviewer + +
appletviewer HelloWorld.html
+ +## Conclusion + +This tutorial concludes the setup of running a simple Java applet. From here you can look at the different methods in the [Graphics library](https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html) and play around 😀 \ No newline at end of file diff --git a/content/blog/2017-06-05-java-swing-components.md b/content/blog/2017-06-05-java-swing-components.md new file mode 100644 index 0000000..eff5468 --- /dev/null +++ b/content/blog/2017-06-05-java-swing-components.md @@ -0,0 +1,205 @@ +--- +id: 2198 +title: Java Swing Components +date: 2017-06-05T23:30:18+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2198 +permalink: /2017/06/java-swing-components/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "161484582559" +kind: + - article +--- +This post, over time, will serve as a reference to myself and others of the different UI components available in the Swing library. This post assumes a general familiarity with setting up a basic Swing application and focuses only on the individual components. + + + +### Buttons + +Buttons are created using the JButton component. The constructor takes the text placed inside the button. + +

+JButton stopBtn = new JButton("Stop");
+
+ + + +You can also add images inside a button. To do that you need to get the image and make it into an icon. The following code grabs the image file “smallpanda.jpg” from the current working directory. + +

+Image img = this.getImage(this.getCodeBase(), "smallpanda.jpg");
+ImageIcon imgIcon = new ImageIcon(img);
+JButton feedBtn = new JButton("Feed", imgIcon);
+
+ +Sometimes, you want to change the location of the text in the button. Like say, we want to place the text in the center horizontally and bottom vertically. + +

+feedBtn.setHorizontalTextPosition(JButton.CENTER);
+feedBtn.setVerticalTextPosition(JButton.BOTTOM);
+
+ +Don’t forget to add your buttons to the screen! + +

+this.add(stopBtn);
+this.add(feedBtn);
+
+ + + +### Labels and Textfields + +One of the most common forms of input is a text field, usually distinguished with a label. Those components are called JTextField and JLabel respectively. The constructor for JTextArea can take just the width of the text field, or another common use is to have already inputed text and its width. + +

+    JLabel nameLabel = new JLabel("Enter in your name: ");
+    
+    // Create an input and set the width to be 10px wide
+    JTextField nameInput = new JTextField(10);
+    //Override nameInput with a field already contains the text "Brandon"
+    //And is 10px wide
+    nameInput = new JTextField("Brandon", 10);
+    
+    this.add(nameLabel);
+    this.add(nameInput);
+
+ + + +### Checkboxes + +Checkboxes are commonly used when giving the possibility for multiple answers. Such as, check all of the foods that you like. + +

+    JCheckBox pizza = new JCheckBox("Pizza");
+    JCheckBox noodles = new JCheckBox("Noodles");
+    JCheckBox rice = new JCheckBox("Rice");
+    this.add(pizza);
+    this.add(noodles);
+    this.add(rice);
+
+ + + +You can even replace the default look of the checkbox with an image. To do this, you need to make image icons for both when it’s checked and when it’s unchecked. + +

+Image checkedImage = this.getImage(this.getCodeBase(), "checked.png");
+Image uncheckedImage = this.getImage(this.getCodeBase(), "unchecked.png");
+
+ImageIcon checkedIcon = new ImageIcon(checkedImage);
+ImageIcon uncheckedIcon = new ImageIcon(uncheckedImage);
+
+JCheckBox checkbox = new JCheckBox("Check Me", uncheckedIcon);
+checkbox.setSelectedIcon(checkedIcon);
+
+this.add(checkbox);
+
+ + + + +### Text Areas + +Text Areas are different from text fields in which it is made to be able to hold multiple lines of text. It’s called JTextArea and its construction takes a width and height as it’s arguments. + +

+JTextArea textarea = new JTextArea(10, 10);
+
+ +By default, when the someone inputs more text than the size can hold, it will automatically grow with the text inputted. To override this behaviour and instead introuduce scroll bars. One must define a ScrollPane and put the TextArea inside of it by using it as the scroll pane’s argument for its constructor. + +

+JScrollPane scrollPane = new JScrollPane(textarea);
+
+ + + +### Radio Buttons + +Radio buttons are used for when you only want one out of many different options to be selected. For this, one needs to define a button group that houses the radio buttons for the user to choose from. This can be achieved with ButtonGroup and JRadioButton respectively. + +

+// Make the radio buttons
+JRadioButton radio1 = new JRadioButton("Pies");
+JRadioButton radio2 = new JRadioButton("Cakes");
+JRadioButton radio3 = new JRadioButton("Cookies");
+
+// Put the radio buttons in a group
+Button Group desserts = new ButtonGroup();
+desserts.add(radio1);
+desserts.add(radio2);
+desserts.add(radio3);
+
+// Add the radio buttons to the screen
+this.add(radio1);
+this.add(radio2);
+this.add(radio3);
+
+ + + +### JList + +To display a list of items that are clickable by the user, you can use a `JList`. JLists require a model that stores the list implementation, we’ll use `DefaultListModel` to achieve this purpose. + +

+DefaultListModel model = new DefaultListModel();
+JList list = new JList(model);
+
+ +To add scrolling capabilities, remember to add it to a scroll pane + +

+JScollPane sp = new JScrollPane(list);
+
+ +You can set the number of items you wish to see in the list. The example below, allows us to see three items in the list. + +

+list.setVisibleRowCount(3);
+
+ +There are a variety of ways to add items to the list. If a number is specified that tells it to place it at the index specified. Starting from the top at zero, to the button. + +

+model.addElement("Apples")
+model.addElement("Cherries");
+model.addElement("Bananas");
+// Adds 'Oranges' to the top
+model.add(0, "Oranges");
+
+ +Sometimes, you want to only let the user select one item. At the end, don’t forget to add the component to the screen! + +

+list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+this.add(sp);
+
+ + + +### JComboBox + +To create a dropdown list of different options, consider using a JComboBox. + +

+JComboBox cb = new JComboBox();
+cb.addItem("Select Food Option");
+cb.addItem("Pizza");
+cb.addItem("Burger");
+cb.addItem("Hot Dog");
+cb.addItem("Steak");
+// Add it to the screen
+this.add(cb);
+
+ + \ No newline at end of file diff --git a/content/blog/2017-06-05-using-system-themes-java-swing.md b/content/blog/2017-06-05-using-system-themes-java-swing.md new file mode 100644 index 0000000..b96b3e4 --- /dev/null +++ b/content/blog/2017-06-05-using-system-themes-java-swing.md @@ -0,0 +1,45 @@ +--- +id: 2192 +title: Using System Themes In Java Swing +date: 2017-06-05T20:36:22+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2192 +permalink: /2017/06/using-system-themes-java-swing/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "161478693279" +mf2_syndication: + - 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/871828083459936257";}' +kind: + - article +--- +The default theme for Java Swing components is a cross-platform theme called “Metal”. I use the Adapta theme for GTK on Linux and this theme does not match at all what my other GUI applications look like. So here, I will describe a simple way to utlize already existent system themes in Java Swing applications. + + + +### Solution + +In the init method of your java application, place the following code. + +

+try {
+    UIManager.setLookAndFeel(UIManager
+                               .getSystemLookAndFeelClassName());
+} catch(Exception e) {}
+
+ +Here the application will attempt to look up the system theme and set that as the default styles for the Swing components. If the lookup fails, then it will default back to the metal theme. + +For more information, check out this page from [Oracle](http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html). + +### Discussion + +If it is so easy to set up applications that look native to each desktop environment, why not have that by default? With the cross platform metal theme, you can ensure that the style of your application is the same across all the operating systems. In this fashion, you don’t need to worry about spacing between components and have full control of the “look and feel” of your application. + +Since I am used to development for the web, I don’t have strong motivation to have an application look the same on all platforms. I prefer the application to match the system theme and look like it was built for the platform that I am on. One loses partial control on the presentation of your application across different desktop environmnets, but with a strong layout, it is possible to make it look organized and integrated. \ No newline at end of file diff --git a/content/blog/2017-08-28-escape-sequences-java.md b/content/blog/2017-08-28-escape-sequences-java.md new file mode 100644 index 0000000..a631270 --- /dev/null +++ b/content/blog/2017-08-28-escape-sequences-java.md @@ -0,0 +1,96 @@ +--- +id: 2236 +title: Escape Sequences in Java +date: 2017-08-28T17:12:00+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2236 +permalink: /2017/08/escape-sequences-java/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "164716848139" +tumblr_crosspostr_crosspost: + - 'N' +kind: + - note +--- +Sometimes you want to format your outputs. This is a quick cheatsheet containing the differerent escape sequences + +  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Character + + Escape Sequence +
+ Newline + + \n +
+ Tab + + \t +
+ Backspace + + \b +
+ Double Quote            + + \” +
+ Single Quote + + \’ +
+ Backslash + + \\ +
\ No newline at end of file diff --git a/content/blog/2017-08-28-obtaining-command-line-input-java.md b/content/blog/2017-08-28-obtaining-command-line-input-java.md new file mode 100644 index 0000000..e32fd5c --- /dev/null +++ b/content/blog/2017-08-28-obtaining-command-line-input-java.md @@ -0,0 +1,136 @@ +--- +id: 2241 +title: Obtaining Command Line Input in Java +date: 2017-08-28T17:37:59+00:00 +author: Brandon Rozek +layout: post +guid: https://brandonrozek.com/?p=2241 +permalink: /2017/08/obtaining-command-line-input-java/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";N;s:10:"author_url";N;s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";N;s:2:"id";N;s:21:"follower_notification";N;s:7:"license";N;s:14:"publication_id";N;s:6:"status";N;s:3:"url";N;}' +mf2_syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +mf2_cite: + - 'a:4:{s:9:"published";s:25:"0000-01-01T00:00:00+00:00";s:7:"updated";s:25:"0000-01-01T00:00:00+00:00";s:8:"category";a:1:{i:0;s:0:"";}s:6:"author";a:0:{}}' +tumblr_post_id: + - "164717769554" +mf2_mp-syndicate-to: + - 'a:1:{i:0;s:4:"none";}' +kind: + - note +--- +To obtain console input for your program you can use the Scanner class + +First import the relevant library + +

+import java.util.Scanner;
+
+ +Then create a variable to hold the Scanner object + +

+Scanner input;
+input = new Scanner(System.in);
+
+ +Inside the parenthesis, the Scanner binds to the System input which is by default the console + +The new varible input now has the ability to obtain input from the console. To do so, use any of the following methods + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Method + + What it Returns +
+ next() + + The next space seperated string from the console +
+ nextInt() + + An integer if it exists from the console +
+ nextDouble()              + + A double if it exists from the console +
+ nextFloat() + + A float if it exists from the console +
+ nextLine() + + A string up to the next newline character from the console +
+ hasNext() + + Returns true if there is another token +
+ close() + + Unbinds the Scanner from the console +
+ +Here is an example program where we get the user’s first name + +

+import java.util.Scanner;
+
+public class GetName {
+  public static void main(String[] args) {
+    Scanner input = new Scanner(System.in);
+    System.out.print("Please enter your name: ");
+    String firstName = input.next();
+    System.out.println("Your first name is " + firstName); 
+  }
+}
+
\ No newline at end of file diff --git a/content/blog/2018-01-22-identifying-misspelled-words-dataset-hunspell.md b/content/blog/2018-01-22-identifying-misspelled-words-dataset-hunspell.md new file mode 100644 index 0000000..f2a6990 --- /dev/null +++ b/content/blog/2018-01-22-identifying-misspelled-words-dataset-hunspell.md @@ -0,0 +1,177 @@ +--- +id: 2250 +title: Identifying Misspelled Words in your Dataset with Hunspell +date: 2018-01-22T05:17:16+00:00 +author: rozek_admin +layout: post +guid: https://brandonrozek.com/?p=2250 +permalink: /2018/01/identifying-misspelled-words-dataset-hunspell/ +medium_post: + - 'O:11:"Medium_Post":11:{s:16:"author_image_url";s:75:"https://cdn-images-1.medium.com/fit/c/200/200/1*06lotWcLMUnKZTN6-Th3IQ.jpeg";s:10:"author_url";s:32:"https://medium.com/@brandonrozek";s:11:"byline_name";N;s:12:"byline_email";N;s:10:"cross_link";s:2:"no";s:2:"id";s:12:"c0ccd543b7e6";s:21:"follower_notification";s:3:"yes";s:7:"license";s:19:"all-rights-reserved";s:14:"publication_id";s:2:"-1";s:6:"status";s:6:"public";s:3:"url";s:104:"https://medium.com/@brandonrozek/identifying-misspelled-words-in-your-dataset-with-hunspell-c0ccd543b7e6";}' +mf2_mp-syndicate-to: + - 'a:1:{i:0;s:22:"bridgy-publish_twitter";}' +tumblr_post_id: + - "169988632939" +mf2_syndication: + - 'a:1:{i:0;s:60:"https://twitter.com/B_RozekJournal/status/955308388384235521";}' +kind: + - article +--- +This article is based on one written by [Markus Konrad](https://datascience.blog.wzb.eu/author/markus_konrad/) at this link https://datascience.blog.wzb.eu/2016/07/13/autocorrecting-misspelled-words-in-python-using-hunspell/ + +I assume in this article that you have hunspell and it's integration with python installed. If not, please refer to the article mention above and follow the prerequisite steps. + +This article is inspired from the need to correct misspelled words in the [Dress Attributes Dataset](https://archive.ics.uci.edu/ml/datasets/Dresses_Attribute_Sales). I'll share with you my initial pitfall, and what I ended up doing instead. + +### Background Information + +Misspelled words are common when dealing with survey data or data where humans type in the responses manually. In the Dress Attributes Dataset this is apparent when looking at the sleeve lengths of the different dresses. + +
dresses_data['SleeveLength'].value_counts()
+
+ +| Word | Frequency | +| -------------- | --------- | +| sleevless | 223 | +| full | 97 | +| short | 96 | +| halfsleeve | 35 | +| threequarter | 17 | +| thressqatar | 10 | +| sleeveless | 5 | +| sleeevless | 3 | +| capsleeves | 3 | +| cap-sleeves | 2 | +| half | 1 | +| Petal | 1 | +| urndowncollor | 1 | +| turndowncollor | 1 | +| sleveless | 1 | +| butterfly | 1 | +| threequater | 1 |
+ +Ouch, so many misspelled words. This is when my brain is racking up all the ways I can automate this problem away. Hence my stumbling upon Markus' post. + +### Automagically Correcting Data + +First, I decided to completely ignore what Markus warns in his post and automatically correct all the words in that column. + +To begin the code, let's import and create an instance of the spellchecker: + +
from hunspell import HunSpell
+spellchecker = HunSpell('/usr/share/hunspell/en_US.dic', '/usr/share/hunspell/en_US.aff')
+
+ +I modified his `correct_words` function so that it only corrects one word and so I can `apply` it along the `SleeveLength` column. + +
def correct_word(checker, word, add_to_dict=[]):
+    "Takes in a hunspell object and a word and corrects the word if needed"   
+    # Add custom words to the dictionary
+    for w in add_to_dict:
+        checker.add(w)
+
+    corrected = ""
+    # Check to see if it's a string
+    if isinstance(word, str):
+        # Check the spelling
+        ok = checker.spell(word)
+        if not ok:
+            # Grab suggestions for misspelled word
+            suggestions = checker.suggest(word)
+            if suggestions:
+                # Grab the best suggestion
+                best = suggestions[0]
+                corrected = best
+            else:
+                # There are no suggestions for misspelled word, return the original
+                corrected = word 
+        else:
+            # Word is spelled correctly
+            corrected = word
+    else:
+        ## Not a string. Return original
+        corrected = word
+    return corrected
+
+ +Now let's apply the function over the `SleeveLength` column of the dataset: + +
dresses_data['SleeveLength'] = dresses_data['SleeveLength'].apply(
+    lambda x: correct_word(spellchecker, x))
+
+ +Doing so creates the following series:
+ +| Word | Frequency | +| -------------- | --------- | +| sleeveless | 232 | +| full | 97 | +| short | 96 | +| half sleeve | 35 | +| three quarter | 17 | +| throatiness | 10 | +| cap sleeves | 3 | +| cap-sleeves | 2 | +| Petal | 1 | +| butterfly | 1 | +| turndowncollor | 1 | +| half | 1 | +| landownership | 1 | +| forequarter | 1 |
+ +As you might be able to tell, this process didn't go as intended. `landownership` isn't even a length of a sleeve! + +### Reporting Misspelled Items and Allowing User Intervention + +This is when I have to remember, technology isn't perfect. Instead we should rely on ourselves to identify what the word should be correctly spelled as. + +Keeping that in mind, I modified the function again to take in a list of the data, and return a dictionary that has the misspelled words as the keys and suggestions as the values represented as a list. + +
def list_word_suggestions(checker, words, echo = True, add_to_dict=[]):
+    "Takes in a list of words and returns a dictionary with mispellt words as keys and suggestions as a list. Also prints it out"
+    # add custom words to the dictionary
+    for w in add_to_dict:
+        checker.add(w)
+    
+    suggestions = {}
+    for word in words:
+        if isinstance(word, str):
+            ok = checker.spell(word)
+            if not ok and word not in suggestions:
+                suggestions[word] = checker.suggest(word)
+                if not suggestions[word] and echo:
+                    print(word + ": No suggestions")
+                elif echo:
+                    print(word + ": " + "[", ", ".join(repr(i) for i in suggestions[word]), "]")
+    return suggestions
+
+ +With that, I can use the function on my data. To do so, I convert the pandas values to a list and pass it to the function: + +
s = list_word_suggestions(spellchecker, dresses_data['SleeveLength'].values.tolist())
+
+ +These are the suggestions it produces: + +
sleevless: [ 'sleeveless', 'sleepless', 'sleeves', 'sleekness', 'sleeve', 'lossless' ]
+threequarter: [ 'three quarter', 'three-quarter', 'forequarter' ]
+halfsleeve: ['half sleeve', 'half-sleeve', 'sleeveless' ]
+turndowncollor: No suggestions
+threequater: [ 'forequarter' ]
+capsleeves: [ 'cap sleeves', 'cap-sleeves', 'capsules' ]
+sleeevless: [ 'sleeveless', 'sleepless', 'sleeves', 'sleekness', 'sleeve' ]
+urndowncollor: [ 'landownership' ]
+thressqatar: [ 'throatiness' ]
+sleveless: [ 'sleeveless', 'levelness', 'valveless', 'loveless', 'sleepless' ]
+
+ +From here, you can analyze the output and do the replacements yourself: + +
dresses_data['SleeveLength'].replace('sleevless', 'sleeveless', inplace = True)
+
+ +### What's the Benefit? + +This is where you ask "What's the difference if it doesn't automatically fix my data?" + +When you have large datasets, it can be hard to individually identify which items are misspelled. Using this method will allow you to have a list of all the items that are misspelled which can let you deal with it in a systematic way. \ No newline at end of file diff --git a/content/blog/DebuggingAndPerformance.md b/content/blog/DebuggingAndPerformance.md new file mode 100644 index 0000000..b98ee88 --- /dev/null +++ b/content/blog/DebuggingAndPerformance.md @@ -0,0 +1,86 @@ +--- +title: "Debugging and Performance" +date: 2019-06-15T10:59:30-04:00 +draft: false +--- + +I've come to like the GNU Debugger (GDB) and the `perf` tool recently. This post will be a short summary of the various interesting commands you can use. + +## GNU Debugger + +To attach gbd to an existing process do the following + +```bash +gdb -p pid_of_process +``` + +Otherwise you can start a new application + +```bash +gdb name_of_executable +``` + +Once it loads it will bring you into it's own `REPL` environment. Usually once this comes up I find it useful to add breakpoints to the program. You can either do it by function name or by line number. + +```bash +(gdb) break FunctionName +``` + +```bash +(gdb) break code.cpp:81 +``` + +If you just started a new application you can begin running the program with whatever arguments you wish + +```bash +(gdb) run -arg1 -arg2 +``` + +If you have attached to a process then you can continue its execution. + +```bash +(gdb) continue +``` + +### Breakpoints + +If you have set a breakpoint, it will stop the processes' execution when it lands on the breakpoint. From here, we can take a look at what's on the stack, print variables, and do whatever other debugging we wish. + +**Print variables on stack:** + +```bash +(gdb) info locals +``` + +**Print a specific variable:** + +```bash +(gdb) print variable_name +``` + +**Show backtrace:** + +```bash +(gdb) bt +``` + +**Continue on with program execution:** + +```bash +(gdb) continue +``` + +## Perf + +I haven't played with `perf` as much but one thing I found that was cool was the `perf top` command. This command gives you samples of which function calls keeps the program the most busy. + +To attach to a process and show samples: + +```bash +perf top -p pid -K +``` + + + + + diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 0000000..9bff67d --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,3 @@ +--- +title: Blog +--- diff --git a/content/blog/abstractdef.md b/content/blog/abstractdef.md new file mode 100644 index 0000000..84a5172 --- /dev/null +++ b/content/blog/abstractdef.md @@ -0,0 +1,77 @@ +--- +title: "Useful Abstract Definitions" +date: 2019-10-27T23:49:57-04:00 +draft: false +--- + +## Chapter 17 + +By a **ring** we mean a set $A$ with operations called addition and multiplication which satisfy the following axioms: + +- $A$ with addition alone is an abelian group +- Multiplication is associative +- Multiplication is distributive over addition + +Since $\langle A, + \rangle$ is an abelian group, there is in $A$ a neutral element for addition. This is called the **zero** element. Also, every element has an additive inverse called its **negative**. + +If multiplication in a ring $A$ is commutative then we say that $A$ is a **commutative ring**. + +If a ring $A$ has a neutral element for multiplication then we say that the neutral element is the **unity** of $A$. + +If $A$ is a ring with unity, there may be elements in $A$ which have a multiplicative inverse. Such elements are said to be **invertible**. + +If $A$ is a commutative ring with unity in which every nonzero element is invertible, then $A$ is called a **field**. + +In any ring, a nonzero element $a$ is called a **divisor of zero** if there is a nonzero element $b$ in a ring such that the product $ab$ or $ba$ is equal to zero. + +An **integral domain** is defined to be a commutative ring with unity that has the cancellation property. Another way of saying this is that an integral domain is a commutative ring with unity and has no zero divisors. + +## Chapter 18 + +Let $A$ be a ring, and $B$ be a nonempty subset of $A$. $B$ is called a **subring** if it satisfies the following properties: + +- Closed with respect to addition +- Closed with respect to negatives +- Closed with respect to multiplication + +Let $B$ be a subring of $A$. We call $B$ an **ideal** of $A$ if $xb, bx \in B$ for all $b \in B$ and $x \in A$. + +The **principle ideal generated by $a$**, denoted $\langle a \rangle$ is the subring defined by fixing an element $a$ in a subring $B$ of $A$ and multiplying all elements of $A$ by $a$. +$$ +\langle a \rangle = \{ xa : x \in A \} +$$ +A **homomorphism** from a ring $A$ to a ring $B$ is a function $f : A \to B$ satisfying the identities: +$$ +f(x_1 + x_2 ) = f(x_1) + f(x_2) \\ +f(x_1x_2) = f(x_1)f(x_2) +$$ +If there is a homomorphism from $A$ onto $B$, we call $B$ a **homomorphic image** of $A$. + +If $f$ is a homomorphism from a ring $A$ to a ring $B$, the **kernel** of $f$ is the set of all the elements of $A$ which are carried by $f$ onto the zero element of $B$. In symbols, the kernel of $f$ is the set +$$ +K = \{x \in A: f(x) = 0\} +$$ +If $A$ and $b$ are rings, an **isomorphism** from $A$ to $B$ is a homomorphism which is a one-to-one correspondence from $A$ to $B$. In other words, it is injective and surjective homomorphism. + +If there is an isomorphism from $A$ to $B$ we say that $A$ is **isomorphic** to $B$, and this fact is expressed by writing $A \cong B$. + +## Chapter 19 + +Let $A$ be a ring, and $J$ an ideal of $A$. For any element $a \in A$, the symbol $J + a$ denotes the set of all sums $j + a$ as $a$ remains fixed and $j$ ranges over $J$. That is, +$$ +J + a = \{j + a : j \in J\} +$$ +$J + a$ is called a **coset** of $J$ in $A$. + +Now think of the set which contains all cosets of $J$ in $A$. This set is conventionally denoted by $A / J$ and reads $A$ mod $J$. Then, $A / J$ with coset addition and multiplication is a ring. + +An ideal $J$ of a commutative ring is said to be a **prime ideal** if for any two elements $a$ and $b$ in the ring, +$$ +ab \in J \implies a \in J \text{ or } b \in J +$$ +Theorem: If $J$ is a prime ideal of a community ring with unity $A$, then the quotient ring $A / J$ is an integral domain. + +An ideal $J$ of $A$ with $J \ne A$ is called a **maximal ideal** if there exists no proper ideal $K$ of $A$ such that $J \subseteq K$ with $J \ne K$. + +Theorem: If $A$ is a commutative ring with unity, then $J$ is a maximal ideal of $A$ iff $A/J$ is a field. + diff --git a/content/blog/adding-fonts.md b/content/blog/adding-fonts.md new file mode 100644 index 0000000..88fd008 --- /dev/null +++ b/content/blog/adding-fonts.md @@ -0,0 +1,13 @@ +--- +title: "Adding Fonts" +date: 2019-05-27T12:15:25-04:00 +draft: false +--- + +**Warning: This blog post partially applies to Ubuntu-based operating systems** + +I wanted to add a font to an image on GIMP. Now I wanted to make it so that the font is available system-wide in case I ever needed it again. + +Following this [blog post from It's FOSS](https://itsfoss.com/install-fonts-ubuntu/) I decided to make a `.fonts` folder in my home directory. After that you can download various font's from [Font Squirrel](https://www.fontsquirrel.com/), [dafont](https://www.dafont.com), [Google Fonts](https://fonts.google.com/), and others and drop the `.otf` or `.ttf` files into the `.fonts` folder. + +Then to finally achieve my goal, I made sure I added `/home/user/.fonts` folder to my fonts as outlined on the [GIMP documentation](https://docs.gimp.org/2.10/en/gimp-using-fonts.html) \ No newline at end of file diff --git a/content/blog/albuquerque.md b/content/blog/albuquerque.md new file mode 100644 index 0000000..57ca1c2 --- /dev/null +++ b/content/blog/albuquerque.md @@ -0,0 +1,105 @@ +--- +id: 2234 +title: Albuquerque Real Estate Multiple Regression model +date: 2017-07-12T01:07:39+00:00 +author: Brandon Rozek +layout: revision +guid: https://brandonrozek.com/2017/07/2227-revision-v1/ +permalink: /2017/07/2227-revision-v1/ +--- +### Introduction + +Albuquerque, New Mexico is a city of thriving culture. The population has grown drastically within the past several years and is a hotspot for New Mexico. Albuquerque’s one-of-a-kind southwestern culture is all around the city, from the quaint shops, Pueblo and Spanish inspired architecture and world famous cuisine, to the music and art of the city. Being the largest city in the state, it has a wide variety of homes across the entire city whether it be within the actual city of Albuquerque ore in the outskirts. Many people flock to the city for the weather. It is a mildly dry climate with roughly 310 days of solid sunshine each year, making it a literal hotspot for people who enjoy the outdoors and warm weather. The city has little to no natural disasters that threaten everyday life, make it a safe place to settle. In the city of Albuquerque, there is a wide variety of living communities throughout the area. As mentioned above, there are different diverse communities. The housing availability is vast as well. The housing market in this region is vast. Because there is little to no potential for natural disasters it causes the market to grow due to less of a liability for increased damage from weather. Albuquerque, has one of the lowest costs of living than anywhere else in the country which makes it a great place to invest in the housing market. The goal of this project is to figure out details of real estate, specifically in the city of Albuquerque, New Mexico. In the dataset given, the predictors available are square footage, age of home, number of features, amount in taxes, and several binary variables. Those binary variables being whether or not the home was of a custom design, is located in a corner location, or if it is located in the northeast quadrant of the city. + +### Descriptive Statistics + +Our dataset features a representative sample of 117 homes in Albuquerque, New Mexico. From this dataset, we can describe the key patterns that arise and build an intuition for what is to come in our inferential statistics section. It is important to build this intuition since it helps when generalizing to a population. + +#### Distribution of Data + +To understand the boxplot of interactions shown by Figure 1, we first need to establish what each of the indices or numbers under the x-axis represent. The first index discloses whether or not the home is located in the northeast quadrant of Albuquerque, New Mexico. The second 1index tells us whether or not the home had a custom design. And finally, the third index indicates whether or not the home is located in the corner of an intersection. From the boxplot of interactions, we can see that homes with a custom design tend to have a higher price than homes that don’t. There are no other patterns from this figure that we can readily pick up in terms of how the different combination of factors affect a home’s price. Figure 2 consists of multiple boxplots each comparing the price distribution of the different levels in all the categorical variables. From this we can reconfirm that having a custom design leads to a higher price distribution. We also see that the Northeast quadrant has a larger variation in price. There does not seem to be any significant difference in the price of homes depending on if it’s located on a corner. Finally, the more features a home has, the larger the variation in prices become. Figure 3 shows a scatterplot matrix of our data. From the matrix we can see the possibility of a linear correlation between price and square footage, as well as, price and tax. There is no evidence, however, of linear correlation between price and the age of the home. This suggests that perhaps age will not become a significant factor in our model. Figure 4 contains histograms of the different quantitative variables. As shown in the figure, the histograms are all right skewed. This shows that the majority of homes are in the lower price range while there are a few homes in the upper price region that might skew our model. Figure 5 shows the distribution of the data in terms of the categorical variables. It is interesting to note that the number of features falls in a gaussian like curve which is unimodal and symmetric at about 4 features. There are more homes that do not have a custom design and do not lie on a corner than ones that do. In this dataset, there are also more homes in the northeast quadrant than homes that are not. Figure 6 shows the distribution of taxes to be right skewed as well. + +#### Effect/Interaction Plots + +In the following section we will consider the effect of different categorical variables on the price of homes in Albuquerque and the other variables. The effect plots are used primarily to build an intuition on an individual variable’s effect on the price of a home. Interaction plots, however, analyze the influence of a variable on another’s effect on the price of a home. If the lines in an interaction plot intersect, it tells us that a categorical variable has a significant influence on another’s effect on the price of a home. The main effect plots in Figure 7 shows us the mean price of a home in relation to the different levels for each of the factors in the dataset. Similar to what was discovered in the boxplot figures, having a custom design increases the price of a home drastically compared to the increase of the price of a home by other factors. Having a home in a non-corner location slightly decreases the value of a home on average. Finally, it is shown in the Feature Effect plot that increases in the number of features increases the price of a home. An interesting thing to note is how in the case of 8 features, the average price of a home decreases. Figures 8, 9, and 10 show the interaction plots of different categorical variable combinations. In Figures 8 and 9, the lines do not intersect, therefore we can conclude that being in the northeast bears no influence on how custom design influences the price of the home and being in the northeast also bears no influence on how the corner location affect on the price. Figure 10, however, shows an interaction between corner location and custom design. This suggests that corner location has an influence on how custom design effects the price. + +#### Missing Data + +In the dataset provided, 44% of the homes are missing some data. Missing data, like outliers, are not to be ignored. To deal with missing data, one needs to know the implications of missing data on the analysis. From there, we can think of several techniques to deal with the absence of the data. One of the most important implications to check is to see if the data is missing at random. If the data is not missing at random, then it taints the representability of the sample, making it harder to generalize to a population. In the dataset provided there are two variables that contain missing data. Figure 11 shows how 42% of the data is missing the age variable and 9% of the data is missing the Tax variable. Looking at the right side of Figure 11, we can see the pattern of missing data in our set. 35% of the data in our set is only missing the age variable, 7% of our data is missing the age and tax variable, and only 2% of our data is missing the tax variable alone. Figure 12 shows us the missing data with respect to quantitative variables such as price, square footage, and tax. As seen in the figure, the missing data is spread equally throughout the distribution. Figure 13 shows us the missing data with respect to the categorical variables in our dataset. As seen in the figure, the proportion of missing data in the binary variables are about the same for each level. When looking at the number of features, however, there is a higher proportion of data missing in the homes with fewer features than in the homes with more features. Looking at the scatterplot matrix of missing values in Figure 14, we can see that the missing values in red are spread out evenly through the observed values in blue. Missing data with respect to age was not considered since the majority of the missing data comes from the age variable. + +### Inferential Statistics + +Now that we’ve described the sample, we can now look forward to generalizing our suspicions to the population. In this section, we define the hypotheses of interest in our model and then consider different techniques that lead up to the final model and analysis. +Hypotheses The main hypothesis of interest is if the model is significant. +➢ H​ 0​ : There is no linear association between the price of homes in Albuquerque, New Mexico and any of the following: square footage, age of the home, tax, number of features, corner location, northeast location, or custom design. +➢ H​ A​ : There is a linear association between the price of homes in Albuquerque, New Mexico and at least one of the following predictors: square footage, age of the home, tax, number of features, corner location, northeast location, or custom design. Afterwards, we consider if square footage, age, tax, number of features, corner location, northeast location, or custom design are significant predictors in the model individually. + +#### Ignore Missing Data Technique + +One of the first regression models we considered is if we ignore all of the missing data. Since 44% of our data have missing values, this drops our degrees of freedom significantly to 61. This technique also doesn’t utilize all of the data, which is prefered so that it doesn’t affect the coefficients of our model. Running the stepwise algorithm to maximize the AIC, we obtain the following model +PRICE = 97.92321 + 0.33638(SQFT) + 0.52308(TAX) + 177.18519(CUST1) − 77.82234(COR1) +Where the p-value of the model is less than 2.2e-16. At a 5% significance level, there is a linear association between the price of the home and at least one of the following predictors: square footage, tax, custom design, or corner location. Looking at the individual t-tests for predictor significance, square footage, tax, and custom design all have a p-value around or less than 0.01 which rejects the null hypotheses of those predictors. This tells us that square footage, tax, and custom design are all significant predictors in our model. However, corner location only have a p-value of 0.09, which at a 5% significant level, fails to reject the null hypothesis. Corner location is not a significant predictor in our model. The residual standard error in this model is $155,400 which is about 15% of the mean price value of a home. The adjusted R​ 2 value is 0.8523, which means that about 85% of the variation in the prices are accounted for in the variation of the model. Not all of the conditions are met for this model and since we ignore a good chunk of the data, this model is not fully appropriate for our usage. In our next attempt, we will increase the number of observations that we include in our analysis. + +#### Remove Age Column Technique + +##### Justification of Removal of Age Variable + +Most of the data missing is in the age variable. Age is also not a significant predictor in the model made in the previous section, therefore, our next idea was to remove the age variable from the dataset. It is important, however, to establish that the age data is truly missing at random and removing it won’t significantly affect the analysis. We do this by removing the only other variable that has missing data (tax) from the dataset. Looking at Figures 17 and 18, it did not change significantly the distribution of missing data with respect to the different variables. This lets us comfortably remove the age column from our dataset. From here, we then repeat the Ignore Missing Data technique. This time since only 9% of the data is missing, our degrees of freedom in this analysis increases from 61 to 102. Having a greater degrees of freedom allows us to have more statistical power in our analysis. + +##### Variable Selection and Test Results + +Running through the stepwise algorithm to maximize AIC, we get the following model +PRICE = 175.16603 + 0.67707(TAX) + 156.81481(CUST1) + 0.20760(SQFT) − 83.40126(COR1) +The p-value of this model is less than 2.2e-16, which at a 5% significance level, leads us to reject the null hypothesis and state that price has a linear association between at least one of the predictors in the model. Looking at the t-tests for predictor significance, all of the p-values are less than 0.05, which leads us to reject all the null hypotheses, and state that all of the predictors in this model: tax, custom design, square footage, and corner location are significant. The residual standard error in this model is $162,300 which is slightly higher from the $155,400 in the previous model. Though the proportion that this residual standard error is of the mean of the price set is the same at 15%. The adjusted R​ 2 value is 0.8213, which means that 82% of the variation in the prices are accounted for by the variation in the model. This dropped from the previous 85% value from the +previous model. The residual standard error and adjusted R​ 2 values indicate that this model is worse in terms of its predictive ability. This model, however, takes more of the data into account, which makes it more accurate when considering the data as a whole and not the subsetted data that arrives from removing the null entries. In this model, we still lose about 9% of our data. In our next model, we will consider a technique that allows us to use the entire dataset. + +#### Multiple Imputation + +To take the entire dataset into account we need to decide how to handle the missing values. Multiple imputation is a technique that randomly samples from the existing distribution to take place of the missing data multiple times. The benefits of multiple imputation is that it preserves the mean and variance of the data. For multiple imputation to work, the data must be missing at +random. In the missing data section, we described how the missing data is spread equally with respect to the different variables. This allows us to say that the Missing at Random condition is met. + +##### Variable Selection and Test Results + +Running the stepwise algorithm to maximize the AIC value, we get the following model +PRICE = 138.09421 + 0.65373(TAX) + 0.23709(SQFT) + 124.31776(CUST2) − 6 7.17475(COR2) +From the F-Test, we can reject the null hypothesis at a 5% significance level due to the fact that the p-value is less than 2.2e-16. This means that there is a linear association between price and one of the predictors: tax, square footage, custom design, and corner office. All of the T-Tests for predictor significance aside from COR2 have a p-value of less than 0.05. Meaning, we reject the appropriate null hypotheses and state that tax, square footage, and custom design are significant predictors. The residual standard error is $167,700 with 112 degrees of freedom. This value corresponds to 16% of the mean price of a home. The adjusted R​ 2 value is 0.8056, which means that about 81% of the variation in the prices is accounted for by this model. The residual standard error and adjusted R​ 2 values are again worse than the previous model. However, since this model uses the entire dataset, we can say that this is a more representative sample of the data than the previous models. To lower the amount of error in this model, we considered removing the outliers. In this model there are six outliers as shown in Figure 19. Since they are significantly far from the middle 50% of the price distribution, we removed them in the following section to better make a model that describes the main portion of the data. + +#### Multiple Imputation without Outliers + +Removing the outliers from the model and running the stepwise algorithm to maximize AIC, we obtain +PRICE = 76.47917 + 0.64130(TAX) + 0.27290(SQFT) + 77.58816(CUST2) +6For the F-Statistic, the p-value is less than 2.2e-16. At a 5% significance level, we reject the null hypothesis and state that there is a linear association between price and at least one of the following: tax, square footage, or custom design. The p-values of the T-Tests for predictor significance tells us that at a 5% significant level. all of the predictors are significant since all of the p-values are less than 0.05. The residual standard error of this model is $112,700 which is 11% of the mean of the dataset. +The adjusted R​ 2 value is 0.8901, which means that 89% of the variation in the prices is accounted for by the variation of the model. In this model, the residual standard error is lower and the adjusted R​ 2 value is higher than the previous models. This tells us that it is a better fit for the data without the outliers. Looking at the outlier effect on the coefficients, we can see that without the outliers the term relating to the corner location goes away from the model. That then significantly changes the +coefficients of CUST2 and the y-intercept. + +##### Checking the Conditions for Inference + +Before we conclude with the analysis, we must first check the conditions for inference to see if the technique is appropriate for our data. +Independence Assumption: +A house’s selling price can depend on another’s so this condition is not met. +Randomization Condition: +The dataset is comprised of a random sample of records of resale of homes which satisfies the +randomization condition. +Straight Enough Condition: +The scatterplot matrix in Figure 20 shows that for the predictors square footage and tax that the +scatterplot is straight enough and doesn’t have any bends or curves. +Equal Variance Assumption: +The residual analysis in Figure 21 shows that the outliers are not spread equally on the +scatterplot. Therefore, the equal variance assumption is not met. +Nearly Normal Condition: +The QQ-Plot in Figure 21 shows that the residuals follow a unimodal and symmetric distribution. +Taking out the outliers in the model also did not introduce any new outliers in the boxplot. +Missing At Random Condition: +7The discussion in the descriptive statistics section about the missing data tells us that the data +is missing evenly with respect to the different variables. Therefore, it is safe to assume that the +data is missing at random +Multicollinearity Condition: +All of the VIF values are lower than 10, therefore this condition is met. + +The conditions for inference are not fully met due to the equal variance assumption. This means that our model will be more inaccurate for some price range of homes than others. Looking at our residual analysis, it appears that the inaccuracies happen when the price of the home is higher. There weren’t many outliers in the dataset (6 out of 117 or 5%) so removing these outliers makes the model more representative to the majority of the houses in the market. Since this model is intended to be used when analyzing prices of homes in the area, it is better not to include the outliers that most people don’t intend to buy. Since the error term is unimodal and symmetric, we can be at ease that there isn’t any other confounding factor in our model. Overall, this is a good model to use for inference and prediction as long as one doesn’t use it to describe the outliers. + +### Conclusion + +The multiple imputation model without outliers is the best model outlined in this paper for describing the price of housing in this region. The formula is re-expressed here +PRICE = 76.47917 + 0.64130(TAX) + 0.27290(SQFT) + 77.58816(CUST2) +This states that for every dollar of tax spent on the home, the home increases on average by $64 given the other parameters stay constant. The same concept applies to square footage and custom design. For every square foot added to the home, the value of it increases on average by $27. Having a home with a custom design increases the value of the home by $7700. This model is more reliable the lower the price of the home is. When it comes to high cost homes, the error produced by the model increases. From this model, we conclude that property tax, square footage, and whether or not a home is built from a custom design are the most significant factors in the price of a home in Albuquerque, New Mexico. \ No newline at end of file diff --git a/content/blog/archivingsites.md b/content/blog/archivingsites.md new file mode 100644 index 0000000..14e9a5e --- /dev/null +++ b/content/blog/archivingsites.md @@ -0,0 +1,17 @@ +--- +title: "Archiving Sites" +date: 2019-08-02T22:42:16-04:00 +draft: false +--- + +I have several old Wordpress sites that are now only alive for archival purposes. I've been trying to migrate off of Wordpress since I don't like having yet another system to manage. Luckily for archival type sites, I don't need the whole backend of Wordpress since I don't actually need any CRUD functionality. (Well I need the R part) + +Solution... wget comes to the [rescue](https://stackoverflow.com/questions/538865/how-do-you-archive-an-entire-website-for-offline-viewing#538878) + +Thanks to user [chuckg](https://stackoverflow.com/users/63193/chuckg), I now know you can run `wget -m -k -K -E https://url/of/web/site` to get a full offline copy of a website. + +[Joel Gillman](https://stackoverflow.com/users/916604/jgillman) expanded out the command to `wget --mirror --convert-links --backup-converted --adjust-extension https://url/of/web/site` + +There are other solutions in that stack overflow post, but something about the simplicity of `wget` appealed to me. + +[Check out this now Wordpress free site of mine!](https://sentenceworthy.com) \ No newline at end of file diff --git a/content/blog/aspell.md b/content/blog/aspell.md new file mode 100644 index 0000000..85bf963 --- /dev/null +++ b/content/blog/aspell.md @@ -0,0 +1,8 @@ +--- +title: "aspell" +date: 2019-12-10T22:20:48-05:00 +draft: false +images: [] +--- + +When I was working on my honors thesis, I realized that I needed a way to spell check the file. After a quick search, I stumbled upon `aspell` which is a `curses` based tool to provide an interactive way for dealing with misspellings. Try it out when you have the chance! \ No newline at end of file diff --git a/content/blog/bashflags.md b/content/blog/bashflags.md new file mode 100644 index 0000000..24b8351 --- /dev/null +++ b/content/blog/bashflags.md @@ -0,0 +1,32 @@ +--- +title: "Bash Flags" +date: 2019-08-06T16:55:47-04:00 +draft: false +--- + +I was creating a bash script and was looking around for a solution for parsing command line arguments. [This StackOverflow post](https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash) has a variety of different solutions available. I want to describe my favorite of these posts. + +[Inanc Gumus](https://stackoverflow.com/users/115363/inanc-gumus) proposed the following: + +```bash +#!/bin/bash + +while [[ "$#" -gt 0 ]]; do case $1 in + -d|--deploy) deploy="$2"; shift;; + -u|--uglify) uglify=1;; + *) echo "Unknown parameter passed: $1"; exit 1;; +esac; shift; done + +echo "Should deploy? $deploy" +echo "Should uglify? $uglify" +``` + +Let me quickly describe what it does. While the number of arguments left to process is greater than zero.... + +- Check to see if the argument matches any of the flags + - If it does... + - If the flag requires an additional argument grab it. Then discard an argument. + - If it doesn't. Error out. + - Then get rid of an argument. + +At the end of the while loop, you would've evaluated all the arguments! \ No newline at end of file diff --git a/content/blog/bashprocesses.md b/content/blog/bashprocesses.md new file mode 100644 index 0000000..d39feb1 --- /dev/null +++ b/content/blog/bashprocesses.md @@ -0,0 +1,28 @@ +--- +title: "Handling Background Processes in Bash" +date: 2019-06-17T19:50:30-04:00 +draft: false +--- + +For multi-process applications, I want to be able to start it up using the `bash` command processor and be able to stop all the processes just by hitting `CTRL-C`. + +As a quick reminder, to have a task run in the background you need to add a `&` at the end of the line. + +```bash +execute_app & +``` + +Previously, I was grabbing the PID of this background process, trapping the interrupt signal and taking the time to send the interrupt signal to all of the background processes. + +You can get the child pid by referencing the variable `$!` after sending a process to the background. + +Now I just use `setsid` to set the process group of the background processes to be the same as the bash process itself. The following demo script here will show the capability. + +```bash +#!/bin/bash +setsid sleep 5 & +setsid sleep 10 & +wait +``` + +This script will send two processes to the background and will wait until all the processes are finished. Hitting `CTRL-C` during execution will send the interrupt signal to all of the processes achieving my goal. diff --git a/content/blog/blogworkflow.md b/content/blog/blogworkflow.md new file mode 100644 index 0000000..bae3b34 --- /dev/null +++ b/content/blog/blogworkflow.md @@ -0,0 +1,31 @@ +--- +title: "Blog Workflow" +date: 2019-10-28T00:16:44-04:00 +draft: false +--- + +You may be curious on how I create content for this blog. There's pros and cons to my approach. One pro is that it's relatively easy for me to crank something out and upload it to my site. The downside is that it's not as easily customizable. + + + +I use Hugo as my static site generator. It works with Markdown files. I begin every blog post by typing + +```bash +hugo new blog/title.md +``` + +This creates a file called `title.md` in `content/blog` with front-matter yaml information such as the title and the datetime that I created the post. + +I then use my favorite Markdown editor `typora` to open up the file in the background. + +```bash +typora content/blog/title.md & +``` + +Write some great words down, compile the website, then sync it to my site! + +```bash +hugo +rsync -Paz --delete public/ brandonrozek.com:/path/to/site/folder +``` + diff --git a/content/blog/borgbackup.md b/content/blog/borgbackup.md new file mode 100644 index 0000000..11eed8d --- /dev/null +++ b/content/blog/borgbackup.md @@ -0,0 +1,55 @@ +--- +title: "Borg Backup" +date: 2019-05-21T22:35:31-04:00 +draft: false +--- + +I started using [Borg Backup](https://www.borgbackup.org/) in order to efficiently and securely do my backups. I did some research before choosing this solution as I required three things: + +- Compression +- Encryption +- Deduplication + +Each point is important on their own. Ideally I would be able to put this onto a cloud solution. Due to this I would want compression and deduplication to keep my costs down and encryption in order to maintain privacy. + +Luckily Borg does all of these things and more! It's also easily available on the AUR and the Ubuntu repositories. + +## Getting Started + +This will be a short post just describing the basic usage of the tool. I haven't fully implemented this tool yet so forgive me if this doesn't match your exact use case. This is also a great way for me to document the basic commands for myself as well. + +First to initialize a borg repo encrypted with a password at `repolocation`: + +```bash +borg init --encryption=repokey repolocation +``` + +Then to create a backup in the repo with key `backup1`: + +```bash +borg create --stats --progress --compression lzma repolocation::backup1 folderToBackup +``` + +You can actually replace the compression algorithm if wanted, here is a short description from their [website](https://borgbackup.readthedocs.io/en/stable/): + +- lz4 (super fast, low compression) +- zstd (wide range from high speed and low compression to high compression and lower speed) +- zlib (medium speed and compression) +- lzma (low speed, high compression) + +To list what backups you have in the repo: + +```bash +borg list repolocation +``` + +To mount and unmount the repository + +```bash +borg mount repolocation mountlocation +``` + +```bash +borg umount mountlocation +``` + diff --git a/content/blog/chirp.md b/content/blog/chirp.md new file mode 100644 index 0000000..ce15ae5 --- /dev/null +++ b/content/blog/chirp.md @@ -0,0 +1,28 @@ +--- +title: "Chirp" +date: 2019-09-27T22:46:52-04:00 +draft: false +--- + +In the land of Ham Radio, you can program your radio with a very popular open source software called `chirp`. For Ubuntu users to install it, it is recommended you use the PPA to keep up to date with radio software... + +```bash +sudo apt-add-repository ppa:dansmith/chirp-snapshots +sudo apt update && sudo apt install chirp-daily +``` + +Once you're in, it is recommended that you download the configuration currently set on your radio and store it somewhere safe. You never know when you'll want the Stock configuration again... + +The way the Software works is that you can store a certain amount of channels into your radio. For the Baofeng F8-HP, 128 channels can be stored. The software gives you a table to manage them. The software is nice since you can cut and paste entries around. + +When you're importing frequencies from various sources, pay attention to what entry numbers you're importing to. Otherwise you might overwrite another import you've made. I recommend adding the following types of frequencies to your radio... + +- Repeaters: Can be added by using RepeaterBook + - I used proximity search. It takes a zip code and the radius in miles of what you want to import. +- Local frequencies: You need a prenium account from Radio Reference in order to obtain these. + - Though honestly, a premium account is $15 for half a year. Not bad if you just go in once and download a bunch of frequencies for your area. Depending on where you live, your area might not have frequencies update all the time... + - Imagine being stuck in traffic and getting to know what's happening around you.... +- National Calling Frequencies +- MURS/FRS/GMRS frequencies +- Marine/Railroad frequencies (if you have space) + diff --git a/content/blog/collabpandocbeamer.md b/content/blog/collabpandocbeamer.md new file mode 100644 index 0000000..71f0067 --- /dev/null +++ b/content/blog/collabpandocbeamer.md @@ -0,0 +1,15 @@ +--- +title: "Collaborating on Beamer Pandoc Slides" +date: 2019-11-22T14:49:19-05:00 +draft: false +--- + +Recently I've been making slides using Pandoc with Beamer. However, I came across the issue where I needed to collaborate with someone using already existing slides written in Markdown. + +Sadly, I don't think this person (and most people for that matter) wants to edit slides in Markdown and use Pandoc. So I needed to convert this into another source material. My original plan was to convert this into a Powerpoint and put it into Google Slides. When I went to convert it using Pandoc, it stripped my math typing and theme. Unfortunately, that wasn't going to work for me. + +The solution I ultimately ended using was the following. +1. Convert the Markdown into Latex +2. Upload the latex document into Overleaf +3. Use the share feature in Overleaf + diff --git a/content/blog/colormanipulation.md b/content/blog/colormanipulation.md new file mode 100644 index 0000000..731c1c2 --- /dev/null +++ b/content/blog/colormanipulation.md @@ -0,0 +1,47 @@ +--- +title: "Color Manipulation with Sass" +date: 2019-05-21T23:10:06-04:00 +draft: false +--- + +There are many times that I need to slightly mess with a color. The easiest way I found to do it is to use one of the many color functions in the program `Sass`. [Sass](https://sass-lang.com/) is a CSS preprocessor, meaning that it has it's own syntax and it compiles down to CSS. I remember using this before CSS variables became a thing and that was one of the main driving points of Sass. + +Since I don't work in Web Development anymore, I don't actually have Sass installed on my computer but instead go to [SassMeister.com](https://www.sassmeister.com/) to do my color manipulations. ThoughtBot already wrote a really nice [post](https://thoughtbot.com/blog/controlling-color-with-sass-color-functions) describing all the different color functions, but I'll quickly describe what I do to mess with colors. + +## Quick Color Manipulation + +Now you do need to write special scss syntax in order for this to work, but luckily most of it you can just copy paste and change what you want. For example, to get Sass to make red 10% lighter you would do the following: + +```scss +p { + color: lighten(red, 10%); +} +``` + +Sass will then output the following: + +```css +p { + color: #ff3333; +} +``` + +And BAM just like that you got the hex code for a lighter version of red. You can also get all crazy and nest statements into each other which is usually what I do when I play with these colors. + +If you rather have the RGBA version of this you can do the following: + +```scss +p { + color: rgba(lighten(red, 10%), 0.5); +} +``` + +And it will output: + +```css +p { + color: rgba(255, 51, 51, 0.5); +} +``` + +So in summary, all you need is to replace the section after `color:` and you're all set for manipulating colors! Check out the [ThoughtBot Post above](https://thoughtbot.com/blog/controlling-color-with-sass-color-functions) in order to see all the variety of functions included with Sass such as saturating, hue-shifting, and much more. \ No newline at end of file diff --git a/content/blog/composesystemd.md b/content/blog/composesystemd.md new file mode 100644 index 0000000..4247e5f --- /dev/null +++ b/content/blog/composesystemd.md @@ -0,0 +1,46 @@ +--- +title: "Ensuring Docker Compose Startup with Systemd" +date: 2019-12-16T20:57:36-05:00 +draft: false +images: [] +--- + +I've been having trouble getting some docker containers such as `nginx` to start automatically on bootup, even with the `restart: always` flag. + +To compensate, I wrote a small systemd script and enabled it on startup. + +`/etc/systemd/system/docker-compose.service` + +```ini +[Unit] +Description=Docker Compose Application Service +Requires=docker.service +After=docker.service + +[Service] +Type=oneshot +User=brandonrozek +Group=brandonrozek +RemainAfterExit=yes +WorkingDirectory=/home/brandonrozek/docker/ +ExecStart=/usr/bin/docker-compose up -d +ExecStop=/usr/bin/docker-compose down +TimeoutStartSec=0 + +[Install] +WantedBy=multi-user.target + +``` + +To enable on startup + +```bash +sudo systemctl enable docker-compose +``` + +To start now + +```bash +sudo systemctl start docker-compose +``` + diff --git a/content/blog/copytoram.md b/content/blog/copytoram.md new file mode 100644 index 0000000..3af8f93 --- /dev/null +++ b/content/blog/copytoram.md @@ -0,0 +1,13 @@ +--- +title: "Copy to RAM Please" +date: 2019-08-02T22:37:12-04:00 +draft: false +--- + +I bought a 1U server recently, and I forgot to purchase a SSD to actually hold data. Since I couldn't hold my excitement to play with the server, I decided to load an operating system entirely into RAM and never turn it off for the meantime. + +I browsed [List of Linux Distributoins that run from RAM](https://en.wikipedia.org/wiki/List_of_Linux_distributions_that_run_from_RAM) and found [Slax](https://www.slax.org/) a [debian](https://www.debian.org/) derivative. + +It's not what I would use for my daily driver but in terms of doing this task its perfect. It loads up quickly and lets me perform nice basic user functions. It's also based on debian so I have a whole repository of packages available I can install. + +Now by default, if you're on a USB it'll try to run in a persistent mode, just press ESC in the boot splash to have the option to copy to ram. \ No newline at end of file diff --git a/content/blog/coqgroups.md b/content/blog/coqgroups.md new file mode 100644 index 0000000..8ba48dc --- /dev/null +++ b/content/blog/coqgroups.md @@ -0,0 +1,6 @@ +--- +title: "Group Theory in Coq" +date: 2019-05-21T22:17:00-04:00 +draft: true +--- + diff --git a/content/blog/coredns.md b/content/blog/coredns.md new file mode 100644 index 0000000..9ef792c --- /dev/null +++ b/content/blog/coredns.md @@ -0,0 +1,90 @@ +--- +title: "coredns" +date: 2019-12-13T02:00:29-05:00 +draft: false +images: [] +--- + +Domain names are the easiest way for a reverse proxy to split up services in a homelab. Since I'm going full docker-compose in my homelab, I decided to use `coredns`. + +The server I'm hosting my services on runs Ubuntu 18.04 at the time of writing. This verison of Ubuntu comes packaged with their own DNS resolver `systemd-resolved` which runs on port 53. Therefore in order to stop this, we need to edit `/etc/systemd/resolved.conf`: + +```ini +DNS=127.0.0.1 +FallbackDNS= +Domains=~. +DNSStubListener=no +``` +You might be wondering about the `~.` option in Domains. From the [Arch Wiki](https://wiki.archlinux.org/index.php/Systemd-resolved), "Without the `Domains=~.` option, systemd-resolved might use the per-link DNS servers." + +You also need to remove the already existing `/etc/resolv.conf` file. +```bash +sudo rm /etc/resolv.conf +``` + +Now to setup `coredns` I used the following docker-compose snippet: +```yaml +coredns: + image: coredns/coredns + command: -conf coredns-config/Corefile + ports: + - 53:53/udp + volumes: + - /Volumes/coredns/coredns-config:/coredns-config/ +``` +Noticed that I mounted the configuration directory in a volume. `coredns` is managed by a configuration file. This would be located under `/Volumes/coredns/coredns-config/Corefile` in the host system. + +Let's say we own the domain example.com and want subdomains of that to point to different to our server. To do that, we need to define a zonefile for that domain name. We will save that under `/Volumes/coredns/coredns-config/homelab.db` in our host system. Every other domain we will either pass to a public DNS server like Google's `8.8.8.8` or you can even use a PiHole. + +Example Corefile: +``` +example.com:53 { + file /coredns-config/homelab.db + log + errors +} + +.:53 { + log + errors + forward . 8.8.8.8 + cache +} +``` +I do recommend that whatever domain you do use for your homelab is one you own. Otherwise you might name conflict with a public service that you would want to access in the future. + +The `cache` directive will cache results from the other DNS provider for quicker delivery at a later point. + +The zonefile `homelab.db` could look like the following: +``` +$TTL 3600 +$ORIGIN example.com. +@ IN SOA ns.example.com. contact.example.com. ( + 2019121301 ; serial + 1d ; refresh + 2h ; retry + 4w ; expire + 1h ; nxdomain ttl + ) + IN NS ns.example.com. +@ IN A 192.168.1.10 +* IN A 192.168.1.10 +@ IN A 10.10.100.10 +* IN A 10.10.100.10 +``` + +In the zone file, `@` means whatever the value of `$ORIGIN` is and `*` is a wildcard meaning any subdomain. You can assign a local LAN address first and then a VPN ip address if you have one set up to access services remotely. + +The serial number needs only to be unique across SOA entries, and is conventionally the date and hour in which the entry was modified. + +I have this setup since all my services are on one physical machine. If you want to split it up through many different machines, specify it by adding the subdomains in place of the `*` or `@`. + +After the `Corefile` and `homelab.db` are made, the DNS server is all ready to be up and running. Just execute `docker-compose up -d coredns` and the DNS server will start happily responding to requests. + +A good way to verify it works is to request an `A` record from your site and an external site. + +```bash +dig @serverip example.com A +dig @serverip google.com A +``` + diff --git a/content/blog/cryptogames.md b/content/blog/cryptogames.md new file mode 100644 index 0000000..ce93e10 --- /dev/null +++ b/content/blog/cryptogames.md @@ -0,0 +1,101 @@ +--- +title: "Cryptographic Games" +date: 2020-01-13T21:35:09-05:00 +draft: false +images: [] +--- + +When analyzing cryptographic algorithms, we characterize the strength of the crypto-system by analyzing what happens in various crypto games. Below are a couple examples of crypto games used in literature. + +Actors typically involved in crypto games: + +| Actor | Role | +| ---------- | ---------------------------------------------------------- | +| Oracle | Encrypts a given message. | +| Challenger | Sets up the game between the oracle and adversary. | +| Adversary | Sends messages to the oracle and makes a guess at the end. | + + + +## Left-Right Game + +Here we will have two oracle's `left` and `right` both with a random key $k$. + +The challenger will create a random bit $b$ which is either $0$ or $1$. + +If the bit is $0$, then the adversary will send messages to `left`. Otherwise, the adversary will send messages to `right`. + +After a certain number of interactions the adversary needs to guess which oracle it is talking to. + +We define the adversary's advantage by the distance the probability is away from $\frac{1}{2}$. +$$ +advantage = |p - \frac{1}{2}| +$$ +Why the absolute value? Well if we only guess correctly $10\%$ of the time, then we just need to invert our guess to be correct $90\%$ of the time. + +``` +Generate key for both oracles +Generate random bit b +while game not done: + advesary generates message m + if b = 0: + send m to left oracle + receive c from left oracle + else: + send m to right oracle + receive c from right oracle +Adversary guesses whether b = 0 or 1 +``` + +## Real-Random Game + +This game is very similar to the last one except one of the oracle's only produces random bitstrings. + +An oracle is initialized with a random key $k$ and the challenger creates a random bit $b$. + +If $b = 0$, then the adversary will send messages to the oracle with the proper encryption function and will receive ciphertexts. Otherwise, the adversary will send messages to the random bitstring generator. + +At the end of the game, the adversary needs to guess whether its talking to a proper oracle or a random bitstring generator. + +The same metric `adversary's advantage` is used to characterize the strength of a crypto-system as the last one. + +``` +Generate key for both oracles +Generate random bit b +while game not done: + advesary generates message m + if b = 0: + send m to proper oracle + receive c from proper oracle + else: + send m to random oracle + receive random bitstring c from random oracle +Adversary guesses whether b = 0 or 1 +``` + +## Random Function - Random Permutation Trick + +One trick that we can use in proofs is to say that two procedures are the same up to a certain point when it diverges. + +Let us define $f$ to be some function that given a bitstring $X$ produces a random bitstring $Y$. + +Now, $image(f)$ is initially undefined since we don't know which bitstrings will be randomly generated. + +However, as we calculate $Y$ we will store it to build up $image(f)$. + +At some point, we'll generate $Y$ that already exists in $image(f)$. In that moment we will split based off of whether the procedure is a random function or random permutation. + +If random function, then just return the same $Y$ and end the procedure. Otherwise, return a random bitstring outside of the $range(f)$ and end the procedure. + +``` +Initialize function f with range(f) empty +Generate different random bitstring X +While f(X) not in range(f): + Add f(X) to range(f) + Generate different random bitstring X +If random function: + return f(X) +Else: + return random bitstring Y not in range(f) +``` + diff --git a/content/blog/ctf.md b/content/blog/ctf.md new file mode 100644 index 0000000..d2d5420 --- /dev/null +++ b/content/blog/ctf.md @@ -0,0 +1,31 @@ +--- +title: "Capture The Flag" +date: 2019-05-22T21:25:22-04:00 +draft: false +--- + +There is an event in Computer Security called "Capture The Flag". The purpose is to test the skills of security engineers and students through a variety of tasks in order to get a pass phrase which is called a flag. I noticed that Dr. Andrew Marshall wanted to set up this event at the University of Mary Washington for a while, so I and a few others decided to help make this a reality for him. + +**I didn't know you studied security?** Well honestly I don't. But that doesn't stop me from learning and creating cool challenges. + +## Challenges I Implemented + +In this post, I'll describe the various challenges I've implemented. I won't give the full problem description or answer just in case the problems get recycled in later years. + +### Web Archive Search + +In this problem I describe a discussion that an alumni and the student has. The alumni has trouble remembering a certain detail of an event held on campus. Key words and descriptions are given about the event and it is the job of the student to find the detail that the alumni wants. + +The juicy part of this problem is that the event is no longer on the current version of the university website. This means that ideally the student would go to the [Web Archive](http://web.archive.org/) to search and find for the information. + +*Funny enough, one contestant found the information by reading a really old publication from the time period described.* + +### Audio Recording + +In this challenge, I recorded a flag in an audio recording and distorted it using various tools in audacity. The idea is that you would get the audio clip and not be able to hear what the flag is and then have to import it into an audio editor of choice and manipulate it until the flag is clear. + +*Sadly no one was able to complete this challenge.* I think I made it too hard by voicing individual characters instead of doing a phrase. This would make ambiguous letters like "B" and "P" barely distinguishable from each other. + +### Hidden Text + +This challenge involves hiding text in the web page through some means. Hidden Text was meant to be one of the easiest problems to ease people onto the competition. You can easily solve this type of challenge by opening up the web inspector tool. \ No newline at end of file diff --git a/content/blog/custom-python-repl.md b/content/blog/custom-python-repl.md new file mode 100644 index 0000000..62c369b --- /dev/null +++ b/content/blog/custom-python-repl.md @@ -0,0 +1,32 @@ +--- +title: "Custom Python REPL" +date: 2019-10-27T23:43:12-04:00 +draft: false +--- + +Are you tired of importing the same libraries and setting up the same variables? Why not just create your own custom REPL? Now of course, we're not going to do it from scratch, but instead utilize what Python already gives us. + +Key Ingridient: + +```bash +python -i prompt.py +``` + +This tells Python to run prompt.py and then take you into an interactive prompt. + +Now let's populate `prompt.py` + +```python +#!/bin/env python +import favorite_libraries + +print("Welcome to your own custom REPL!") +print("Type help('function_name') to get a more detailed description on some of your own custom functions!") + +def help(function_name): + if function_name is "help": + print("Your very own help tool!") + else: + print("Sorry we don't have a help written for that yet :(") +``` + diff --git a/content/blog/digialmodes.md b/content/blog/digialmodes.md new file mode 100644 index 0000000..bae96c2 --- /dev/null +++ b/content/blog/digialmodes.md @@ -0,0 +1,78 @@ +--- +title: "Getting started with Digital Modes in Linux" +date: 2019-09-04T09:52:21-04:00 +draft: false +--- + +This blog post is going to describe what steps I took to be able to decode signals using digital modes. Hardware wise, you will either need a RTL-SDR receiver or a transceiver radio with a cable plugging into the computer's soundcard. + +## Software Required + +- Gqrx (depends on GNU Radio) + + - This is if you are trying to work with RTL-SDR + - It acts as a AM/FM/CW/etc demodulator for the data sent by the equipment + +- Fldigi + + - This is what decodes the protocol used to package the data + - It acts as a modem and provides capability to transmit data using a transceiver + +- Pavucontrol + + - This connects both Gqrx and Fldigi if using RTL-SDR + +As you can see, if you are only using a transceiver then you can skip the parts mentioning Gqrx and Pavucontrol + +## Process + +### Gqrx + +When you first open up Gqrx, it'll ask you to configure the device. I have the RTL2832U, so if you have the same tool... + +Select the profile partially labeled RTL2832U. If you want to look at frequencies between 0 and 28MHz then add to the device string "direct_samp=3". Otherwise don't add that string. + +You can keep the rest of the settings the same. + +### Fldigi + +When you first open up Fldigi, it'll ask you for our operator info. + +| Field | description | +| ----------------- | ----------------------------------------- | +| Station Callsign | Your callsign | +| Station QTH | City, State | +| Station Locator | Your grid code. (Can look this up on QRZ) | +| Operator Callsign | Your callsign | +| Operator Name | Your name | +| Antenna | Your antenna type | + +In Audio->Devices, make sure you select the physical device if you're using a transceiver, otherwise select PulseAudio. + +You can keep the rest of the settings as the default. + +### Pavucontrol + +Finally to link the two, run the following lines in bash to create a sink in order to push the audio from Gqrx to Fldigi. + +```bash +pacmd load-module module-null-sink sink_name=MyLoopback +pacmd update-sink-proplist MyLoopback device.description=MyLoopback +pacmd load-module module-loopback sink=MyLoopback +``` + +Now open up `pavucontrol`. On the Playback tab, change the output device of GQRX to be "MyLoopback" + +On the Recording tab, change the input of fldigi to "Monitor of Null Output" + +## Conclusion + +Now the software is sufficiently setup to be able to receive and decode signals. Best of luck finding things out there! + +## Beginner Pitfalls + +Since I'm also a beginner, I will share what I got stuck on and how you can avoid it. + +Make sure that you know the appropriate mode to demodulate the signal. I've had luck getting information from https://www.sigidwiki.com/wiki/Signal_Identification_Guide + +-> This needs to be configured on both Gqrx and Fldigi \ No newline at end of file diff --git a/content/blog/discoveringhamradio.md b/content/blog/discoveringhamradio.md new file mode 100644 index 0000000..ee0591c --- /dev/null +++ b/content/blog/discoveringhamradio.md @@ -0,0 +1,13 @@ +--- +title: "Discovering Ham Radio" +date: 2019-07-01T22:06:23-04:00 +draft: false +--- + +I feel like Ham Radio has been hiding in the background as I move through life. I knew someone that kept a Ham radio in his car, Noah talks about it frequently on his [podcast](http://www.asknoahshow.com/), and it seemed like the next step after [playing with](https://github.com/brandon-rozek/radiotuner) [software defined radio](https://www.amazon.com/RTL-SDR-Blog-RTL2832U-Software-Telescopic/dp/B011HVUEME/ref=sr_1_3). + +One of the things that I think pushed me over to wanting to get my Technician's license is the discovery of [digital data modes](http://www.arrl.org/digital-data-modes). Hams even have their own [email](https://www.winlink.org/)! + +Why is this more interesting than Internet? Well Ham Radio doesn't need any physical infrastructure setup (other than your radio and maybe some repeaters) to get you connected to other people. In fact, Hams often [volunteer](http://www.arrl.org/public-service) in natural disasters when the phone systems are down. + +This convinced to buy a [study guide](https://www.amazon.com/ARRL-Radio-License-Manual-Spiral/dp/1625950829/ref=sr_1_6) and start preparing to take my technicians test this summer. If you're interested in Ham Radio, please contact me at my email on my home page :) diff --git a/content/blog/docker-image-bash.md b/content/blog/docker-image-bash.md new file mode 100644 index 0000000..0a01784 --- /dev/null +++ b/content/blog/docker-image-bash.md @@ -0,0 +1,48 @@ +--- +title: "Advanced Docker Image Construction with Bash" +date: 2019-12-26T21:01:37-05:00 +draft: false +images: [] +--- + +On current versions of Docker, you can't mount volumes during image construction. This poses an issue for me as I don't want to replicate gigabytes of data already existing on my disk when it won't appear on the final build. Therefore, instead of building an image with a traditional Dockerfile, we're going to use a bash script on a running base image container and export the filesystem to create the image from. + +So first run the base image with the mounts that you want + +```bash +docker run -v /mnt:/mnt -td --name containername baseimage /bin/bash +``` + +Then copy whatever `setup` script you have and execute it on the running container + +```bash +docker cp setup containername:/setup +docker exec -it containername /setup +``` + +Once the setup script finalizes, we can export the container filesystem into a file called `image.tar` + +```bash +docker export --output="image.tar" containername +``` + +Once we've exported the filesystem, we can get rid of the existing container + +```bash +docker stop containername && docker rm containername +``` + +Now create a `Dockerfile` with the following: + +```dockerfile +FROM scratch +ADD image.tar / +CMD ["bin/bash"] +``` + +Now you can create the image by building the Dockerfile + +```bash +docker build -t finalimagename . +``` + diff --git a/content/blog/externalmediaformats.md b/content/blog/externalmediaformats.md new file mode 100644 index 0000000..fd41045 --- /dev/null +++ b/content/blog/externalmediaformats.md @@ -0,0 +1,18 @@ +--- +title: "External Media Formats" +date: 2019-05-22T22:03:38-04:00 +draft: false +--- + +I received an external SSD recently and I decided that it would be a great place to offload some of my backups. Before I got started, I became curious as to what filesystem to put on the SSD. After some research, it seems that if I want to be able to access it using Windows I am actually quite limited. In fact only three make sense: + +- FAT32 +- exFAT +- NTFS + +Now FAT32 is a legacy filesystem, Windows 95 type of legacy. So let's rule that one out. exFAT is supposed to be based on FAT32 but increases the file size limits significantly. It is also known for being very slim and as such does not having journaling support. NTFS is the filesystem that Windows 10 uses for default for it's installation. That file system supports journaling. + +I ended up going with NTFS due to its journaling support. Why is journaling important to me? Well this helps keep the file system internally consistent. The details are outside the scope of this post, but [Wikipedia has a nice entry](https://en.wikipedia.org/wiki/Journaling_file_system) about it. + +Well as it turns out, the drive that I was going to use already was formatted as NTFS. Though for sake of completeness, I will say that you can format drives with tools like `parted`, `gparted`, and `partitionmanager`. Just make sure that the drive you're formatting is what you think it is! + diff --git a/content/blog/fmradiotuner.md b/content/blog/fmradiotuner.md new file mode 100644 index 0000000..fbedf78 --- /dev/null +++ b/content/blog/fmradiotuner.md @@ -0,0 +1,26 @@ +--- +title: "FM Radio Tuner" +date: 2019-05-21T22:08:54-04:00 +draft: true +--- + +I recently bought a [RTL-SDR Receiver](https://www.amazon.com/RTL-SDR-Blog-RTL2832U-Software-Telescopic/dp/B011HVUEME/ref=sr_1_3) off of Amazon to get started with [Software Defined Radio](https://en.wikipedia.org/wiki/Software-defined_radio). To start off, I thought that it would be great if I can write a fm receiver. + +To begin you will need to install `gnuradio` and follow the following [instructions](https://osmocom.org/projects/rtl-sdr/wiki/Rtl-sdr). + +## GNURadio + + + + + +## QT + + + + + +## Modifying GNURadio Python Script + + + diff --git a/content/blog/gitlabcicd.md b/content/blog/gitlabcicd.md new file mode 100644 index 0000000..dba7ccc --- /dev/null +++ b/content/blog/gitlabcicd.md @@ -0,0 +1,9 @@ +--- +title: "Gitlab CI/CD" +date: 2019-07-01T21:36:56-04:00 +draft: false +--- + +One of the greatest benefits I believe of integrating Gitlab's CI/CD into your workload is code linting and building. This immediately eliminates the easy mistakes that developers make and wastes less people's time. + +I'm working towards getting the build setup just right in one of the projects I'm currently working. However, in the meantime, Gitlab supports running it's CI/CD jobs under the `shell executor`. I would like to go to the default Docker route in the future once I figure out all of the dependencies of the project I'm building. \ No newline at end of file diff --git a/content/blog/gitlens.md b/content/blog/gitlens.md new file mode 100644 index 0000000..3991a88 --- /dev/null +++ b/content/blog/gitlens.md @@ -0,0 +1,12 @@ +--- + +title: "Git Lens" +date: 2019-10-27T23:38:45-04:00 +draft: false +--- + +Git Lens is a great Visual Studio code extension. It annotates the line your cursor is on with the commit it came from. Extreemely useful for determining the reason that line of code is written or even who wrote it. + +Images from the github page. (If they still exist when you read this) + +![Current Line Blame](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/docs/current-line-blame.png)![Git Code Lens](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/docs/code-lens.png) \ No newline at end of file diff --git a/content/blog/groupssimplified.md b/content/blog/groupssimplified.md new file mode 100644 index 0000000..31cbfa6 --- /dev/null +++ b/content/blog/groupssimplified.md @@ -0,0 +1,38 @@ +--- +title: "Groups Simplified" +date: 2019-12-10T21:40:00-05:00 +draft: false +images: [] +--- + +This post is inspired by the book "Term Rewriting & All That" by Franz Baader and Tobias Nipkow. + +Let us have a set $G$ together with a binary operation $*$. We will use multiplicative notation throughout meaning $ab = a * b$. Let $x, y, z \in G$. If $\langle G , * \rangle$ has the following properties: + +1. $(x y)z = x (y z)$ +2. $ex = x$ +3. $x^{-1} x = e$ + +for some fixed $e \in G$, then we say that $\langle G, * \rangle$ is a group. In class, we needed to show that $xe = x$ and $xx^{-1} = e$. However, these can be derived by the prior properties. + +### Prove $xx^{-1} = e$ +\begin{align*} +e &= (xx^{-1})^{-1}(x x^{-1}) \\\\ +&= (xx^{-1})^{-1} (x (ex^{-1})) \\\\ +&= (xx^{-1})^{-1} (x ((x^{-1} x) x^{-1})) \text{ ----- (A)} \\\\ +&= (x x^{-1})^{-1} (x (x^{-1} x)x^{-1}) \\\\ +&= (x x^{-1})^{-1}((x x^{-1})xx^{-1}) \\\\ +&= (x x^{-1})^{-1} ((xx^{-1}) (x x^{-1})) \\\\ +&= ((x x^{-1})^{-1}(x x^{-1})) (x x^{-1}) \\\\ +&= e(xx^{-1}) \\\\ +&= xx^{-1} +\end{align*} +### Prove $xe = x$ + +Once we showed $xx^{-1} = e$, the proof of $xe = e$ is simple. +\begin{align*} +x &= ex \\\\ +&= (xx^{-1})x \\\\ +&= x(x^{-1}x) \\\\ +&= xe +\end{align*} diff --git a/content/blog/haskellrealsequences.md b/content/blog/haskellrealsequences.md new file mode 100644 index 0000000..950b89d --- /dev/null +++ b/content/blog/haskellrealsequences.md @@ -0,0 +1,49 @@ +--- +title: "Real Analysis Sequences in Haskell" +date: 2019-05-21T22:18:21-04:00 +draft: false +--- + +In Real Analysis it is useful to look at terms of a sequence. One of the best ways I've found to do this is in believe it or not Haskell. This is mainly for these two reasons + +- Support for infinite data structures + +- Built-in Data Type to keep fractional precision + +## Code + +Let's get started, first let us define a sequence by the following: +$$ +f(1) = 1, f(2) = 2, f(n) = \frac{1}{2}(f(n - 2) + f(n - 1)) +$$ +That is equivalent to the following haskell code: + +```haskell +f :: Integral a => a -> Ratio a +f 1 = 1 +f 2 = 2 +f n = 0.5 * (f (n - 2) + f (n - 1)) +``` + +Now to generate the sequence we just need to map $f$ onto the natural numbers. + +```haskell +nsequence = map f [1..] +``` + +If you want to look at specific subsequences, such as even or odd: + +```haskell +odd_generator n = 2 * n - 1 +odds = map odd_generator [1..] + +even_generator n = 2 * n +evens = map odd_generator [1..] +``` + +To look at the differences between each term: + +```haskell +diff x = map (\(a, b) -> a - b) $ zip (tail x) (init x) +``` + diff --git a/content/blog/limitbandwidth.md b/content/blog/limitbandwidth.md new file mode 100644 index 0000000..9900477 --- /dev/null +++ b/content/blog/limitbandwidth.md @@ -0,0 +1,37 @@ +--- +title: "Limit Bandwidth through Terminal" +date: 2020-01-15T19:51:45-05:00 +draft: false +images: [] +--- + +Have you ever wondered how an application or a system would operate under low bandwidth environments? Luckily `wondershaper` is a tool to help with just that! + +```bash +sudo apt install wondershaper +``` + +To get started, first find out the network `interface` that you want to throttle. + +```bash +ip addr show +``` + +To show the state of the interface, + +```bash +sudo wondershaper [interface] +``` + +To set the bandwidth, + +```bash +sudo wondershaper [interface] [downlink] [uplink] +``` +where downlink and uplink are defined in kilobits per second. + +To clear the rules, + +```bash +sudo wondershaper clear [interface] +``` \ No newline at end of file diff --git a/content/blog/linuxdesktopicons.md b/content/blog/linuxdesktopicons.md new file mode 100644 index 0000000..88f8960 --- /dev/null +++ b/content/blog/linuxdesktopicons.md @@ -0,0 +1,21 @@ +--- +title: "Linux Desktop Icons" +date: 2019-06-03T21:05:37-04:00 +draft: false +--- + +I get asked a decent number of times how to add desktop icons on Linux. Luckily it's incredibly easy. [It's a `freedesktop` standard](http://standards.freedesktop.org/desktop-entry-spec/latest/). + +In fact the simplest file would follow the format: + +```yaml +[Desktop Entry] +Name=Application Name +Exec=/path/to/executable -randomFlag +Icon=/optional/path/to/icon +Terminal=false +Type=Application +``` + +Once you have this saved to `yourapplication.desktop` move it to either `/usr/share/applications` if you want it system-wide or `/home/user/.local/share/applications` if you want it just for your `user`. + diff --git a/content/blog/livedoc.md b/content/blog/livedoc.md new file mode 100644 index 0000000..9601a8e --- /dev/null +++ b/content/blog/livedoc.md @@ -0,0 +1,21 @@ +--- +title: "Live Documentation" +date: 2019-09-27T23:07:19-04:00 +draft: false +--- + +This blog post is mostly for one of my teams in which I use Jupyter Notebooks for documentation. Perhaps after reading this post, you the reader can understand why it might be beneficial to use Jupyter Notebooks as a form of documentation. + +## Why? + +So why Jupyter Notebooks? + +- Follows the literate programming approach. You can write text explaining a feature and then immediately show code and it's result. +- It's modifiable. If your user wants to play around with the documentation, the environment is set up for them to do so. +- It's exportable. Let's say another user doesn't want to bother setting it up. Well it's super simple to just export the notebook as a PDF and send that to them instead. + +## Setting up + +Jupyter Notebooks are part of the [Project Jupyter](https://jupyter.org/) suite of products. You can install it via a `pip` package, but it is more commonly installed via the [Anaconda Distribution](https://www.anaconda.com/) + +Once you have that installed, run `jupyter lab` in the directory that you wish to execute code from. You might need to be in the `bash` shell for this to work since the installer modifies those environmental variables. \ No newline at end of file diff --git a/content/blog/localrepoiso.md b/content/blog/localrepoiso.md new file mode 100644 index 0000000..6a5ddeb --- /dev/null +++ b/content/blog/localrepoiso.md @@ -0,0 +1,29 @@ +--- +title: "Local Repo From Live Installer" +date: 2019-08-30T20:26:53-04:00 +draft: false +--- + +I'm going to share my experience setting up a local repo from a CentOS live CD. These instructions should work similarly in REHL. + +When working with off-network systems, it is often useful to have the base packages on the system after the installation process. Luckily the base packages are commonly included in the ISO installer. + +First I'm going to assume that you've mounted the ISO at `/mnt`. + +```bash +sudo mkdir -p /repos/local +sudo rsync -Paz /mnt/Packages /repos/local/Packages +sudo rsync -Paz /mnt/repodata /repos/local/repodata +``` + +Then create the file `/etc/yum.repos.d/local.repo` + +```yaml +[local] +name=Local Repo +baseurl=file:///repos/local/ +gpgcheck=0 +enabled=1 +``` + +Now you're all set to go with the packages on the Live CD! \ No newline at end of file diff --git a/content/blog/lxdtmpfs.md b/content/blog/lxdtmpfs.md new file mode 100644 index 0000000..dc9de48 --- /dev/null +++ b/content/blog/lxdtmpfs.md @@ -0,0 +1,102 @@ +--- +title: "LXD on tmpfs" +date: 2019-12-31T22:35:21-05:00 +draft: false +images: [] +--- + +Container images are designed to be as small as possible. Wouldn't it be cool if we can hold entire containers in RAM? This post outlines how to accomplish this using LXD. It turns out that it is a lot easier to setup custom storage pools on LXD than with Docker. + +## Setting up tmpfs + +`tmpfs` is a temporary filesystem that resides in memory. To get started, first create a directory that you want to mount with `tmpfs` + +```bash +mkdir /tmp/ramdisk +``` + +To only do this temporarily, then you can run the following command + +```bash +sudo mount -t tmpfs -o size=4G myramdisk /tmp/ramdisk +``` + +You can replace `4G` with any size less than your current RAM size. + +To set it up permanently, you will have to edit `/etc/fstab` + +``` +myramdisk /tmp/ramdisk tmpfs defaults,size=3G,x-gvfs-show 0 0 +``` + +## Setting up LXD + +LXD is a lightweight container hypervisor in Linux. To install and setup, please follow the beginning sections of https://linuxcontainers.org/lxd/getting-started-cli/ + +Once you've setup the initial configuration with `lxd init`, we can create a new storage pool using our newly created `tmpfs` + +```bash +lxc storage create tmplabel dir source=/tmp/ramdisk +``` + +We can then create a container that will use this storage pool + +```bash +lxc launch ubuntu:18.04 mycontainer -s tmplabel +``` + +In the last command, the `-s` flag indicates which storage pool we want to use. + +With this, our entire container filesystem lives in RAM! + +## (Optional) Setting up mounts + +One downside to putting the entire filesystem in RAM is that it isn't persistent across reboots. You can think of the container then as ephemeral and setup mountpoints to the host in order to save important configuration information. + +If the mount point is configured to be world writable or you only need it to be readonly, then this is very simple to setup! + +```bash +lxc config device add mycontainer dirlabel disk source=/path/on/host path=/path/on/container +``` + +This is because files in the container are marked as `nobody:nogroup`. If you want to be able to write to the mounted directory that's not setup to be world-writable then there's extra steps we need to take. + +Most of the following information is taken from: https://tribaal.io/nicer-mounting-home-in-lxd.html + +Let's say that you want LXD to be able to write to a folder that you own. First we need to allow LXD to remap your user ID. + +```bash +echo "root:$UID:1" | sudo tee -a /etc/subuid /etc/subgid +``` + +We only need to do this once per host system. + +The Ubuntu container has a user called `ubuntu` with UID 1000. We can remap that userid, otherwise you would have to create another user on the container to remap. + +If you create another user, make sure you get its id for the next command: + +```bash +# In the container +id -u username +``` + +For the rest of this tutorial, we will assume that you have a user named ubuntu with UID 1000. + +Once LXD is able to remap your user id, you can tell it to do so for the container of interest. + +```bash +lxc config set mycontainer raw.idmap "both $UID 1000" +``` + +Now to setup the mount + +```bash +lxc config device add myubuntu homedir disk source=$HOME path=/home/ubuntu +``` + +Restart the container and now the `ubuntu` user will be able to write to the mount! + +```bash +lxc restart mycontainer +``` + diff --git a/content/blog/male-vs-female-life-expectancy2052-revision-v1-Male-vs-Female-Life-Expectancy.md b/content/blog/male-vs-female-life-expectancy2052-revision-v1-Male-vs-Female-Life-Expectancy.md new file mode 100644 index 0000000..747b121 --- /dev/null +++ b/content/blog/male-vs-female-life-expectancy2052-revision-v1-Male-vs-Female-Life-Expectancy.md @@ -0,0 +1,208 @@ +--- +id: 2169 +title: Male vs Female Life Expectancy +date: 2017-03-16T14:12:40+00:00 +author: rozek_admin +layout: revision +guid: https://brandonrozek.com/2017/03/2052-revision-v1/ +permalink: /2017/03/2052-revision-v1/ +--- +![](https://brandonrozek.com/wp-content/uploads/2017/03/LifeExpectancyBoxplot.png) + +## Do females live longer than males? + +It is well known that females live longer than males, but does that statement hold statistically? Matthew Martinez and I set out to find out. + + + +## Population and the hypothesis + +Our population of concern is citizens of the United States. We found a dataset on [WorldLifeExpectancy](http://www.worldlifeexpectancy.com/) listing by county the average life expectancy for both males and females. With this we form our null and alternative hypothesis + +H0: The average life expectancy for both males and females are the same in the United States + +HA: The average female life expectancy is higher than the average male life expectancy in the United States + +## Data preparation + +Since the website gives us an overlook at all of the counties in the United States we want to take a small sample of that so we can perform statistics. Using the entire dataset will result in looking at population parameters which doesn’t leave room for inference. + +A random number was chosen to pick the state and then the county. This was done a total of 101 times. The CSV file is located [here](https://brandonrozek.com/wp-content/uploads/2017/03/LifeExpectancy.csv) for convenience. + +## R Programming + +For the rest of this article, we will use R for analysis. This article will focus more on the analysis, however, than the R code. + +Read the CSV file into R + +
rm(list=ls())
+
+# Read in file
+LifeExpectancy = read.csv("~/LifeExpectancy.csv")
+maleExpectancy = LifeExpectancy$Life.Expectancy.Male
+femaleExpectancy = LifeExpectancy$Life.Expectancy.Female
+
+ +## Summary Statistics + +Before we begin our inferential statistics, it is a good idea to look at what we have in our sample. It will give us a good feeling for what we’re working with and help us answer some questions involving the assumptions in parametric tests. + +We’re interested in the minimum, mean, maximum, and interquartile range of the data + +

+# Summary statistics
+male_row = c(min(maleExpectancy), mean(maleExpectancy), max(maleExpectancy), IQR(maleExpectancy))
+female_row = c(min(femaleExpectancy), mean(femaleExpectancy), max(femaleExpectancy), IQR(femaleExpectancy))
+summary = rbind(male_row, female_row)
+colnames(summary) = c("Min", "Mean", "Max", "IQR")
+rownames(summary) = c("Male", "Female")
+
+ +Looking at the table below, we can see that the average male lives to be around 69 years old in our sample while the average female lives to be about 71 years old. One interesting thing to note is how small the variation is between all the counties life expectancy that we sampled. + +
summary
+##         Min   Mean  Max   IQR
+## Male   69.0 74.952 80.9 2.775
+## Female 76.1 80.416 84.1 2.350
+ +## Inferential Statistics + +From here on out, we will perform a hypothesis test on the two hypothesis stated earlier in the text. + +Since our data is quantitative in nature, we will attempt to perform a two sample t-test + +### Check for Assumptions + +Performing a t-test comes with several assumptions we need to check before confidently reporting our results. + +Independence Condition: One county’s life span does not affect the lifespan of another. + +Independent groups assumption: The lifespan of a male does not directly impact a lifespan of a female. + +Nearly Normal Condition: We need to check the histograms to see if they’re unimodal and symmetric and check to see if any outliers exist + +The male life expectancy distribution appears to be unimodal and symmetric. + +
# Check for normality
+hist(maleExpectancy, main = "Male Life Expectancy", xlab = "Age")
+ + + +Same with the female life expectancy distribution + +
hist(femaleExpectancy, main = "Female Life Expectancy", xlab = "Age")
+ + + +Looking at the boxplot, we can see that the IQR of the female life expectancy is higher than the one of the males. The hypothesis test will show us if this is of significant difference. On the male’s side there are two outliers. This violates the Nearly Normal Condition so we must proceed with caution in our test. + +
boxplot(maleExpectancy, femaleExpectancy, names = c("Male Life Expectancy", "Female Life
+                                                        Expectancy"), ylab = "Age")
+ + + +Since the nearly normal condition was not met, we do not meet the assumptions necessary to perform a t-test. However, since the condition was violated by an outlier, let us perform a t-test with the outlier and without the outlier and compare the results. + +### Calculate the Test Statistic + +Let us conduct a two sample t-test with the alternative hypothesis being that the female average life expectancy is greater than that of the males + +Running the test below shoes us a p-value of less than 0.001. This tells us that the probability of obtaining a sample as extreme as the one obtained is close to zero. Therefore at a significance level of 5%, we reject the null hypothesis and state that there is strong evidence to suggest that females have a greater life expectancy that that of males. + +
# Test alternative hypothesis
+t.test(femaleExpectancy, maleExpectancy, alternative='g')
+ +
## 
+##  Welch Two Sample t-test
+## 
+## data:  femaleExpectancy and maleExpectancy
+## t = 18.858, df = 182.48, p-value < 2.2e-16
+## alternative hypothesis: true difference in means is greater than 0
+## 95 percent confidence interval:
+##  4.984992      Inf
+## sample estimates:
+## mean of x mean of y 
+##    80.416    74.952
+ +In fact, we are 95% confident that the difference between the average female life expectancy and the average male life expectancy in the United States is between 5 and 6 years. Females live on average 5-6 years longer than males in the United States. + +# Find confidence interval<br /> +t.test(femaleExpectancy, maleExpectancy) + +
## 
+##  Welch Two Sample t-test
+## 
+## data:  femaleExpectancy and maleExpectancy
+## t = 18.858, df = 182.48, p-value < 2.2e-16
+## alternative hypothesis: true difference in means is not equal to 0
+## 95 percent confidence interval:
+##  4.892333 6.035667
+## sample estimates:
+## mean of x mean of y 
+##    80.416    74.952
+ +### Outlier Analysis + +We cannot forget that we had outliers in our dataset. This might affect the results of our test. The point of outlier analysis is to see if such changes are significant. + +First let us remove the outliers in R + +
# Remove outliers
+maleExpectancy2 = maleExpectancy[!maleExpectancy %in% boxplot.stats(maleExpectancy)$out]
+
+ +Then let us check the histogram and boxplots to see if the nearly normal condition is now met. + +Looking at the boxplot, there are no more outliers present + +

+# Check graphs again
+boxplot(maleExpectancy2, ylab = "Age", main = "Male Life Expectancy w/o Outliers")
+ + + +The histogram still appears to be unimodal and symmetric + +
hist(maleExpectancy2, xlab = "Age", main = "Male Life Expectancy w/o Outliers")
+ + + +Without the outliers present, the nearly normal condition is now met. We can perform the t-test. + +We can see that the hypothesis test returns the same results as before, this tells us that the outliers did not have a significant impact on our test results + +
# Test new alternative
+t.test(femaleExpectancy, maleExpectancy2, alternative='g')
+ +
## 
+##  Welch Two Sample t-test
+## 
+## data:  femaleExpectancy and maleExpectancy2
+## t = 19.471, df = 184.03, p-value < 2.2e-16
+## alternative hypothesis: true difference in means is greater than 0
+## 95 percent confidence interval:
+##  5.000048      Inf
+## sample estimates:
+## mean of x mean of y 
+##  80.41600  74.95204
+ +Redoing the confidence intervals, we can see that it did not change greatly + +
# Find new confidence interval
+t.test(femaleExpectancy, maleExpectancy2)
+ +
## 
+##  Welch Two Sample t-test
+## 
+## data:  femaleExpectancy and maleExpectancy2
+## t = 19.471, df = 184.03, p-value < 2.2e-16
+## alternative hypothesis: true difference in means is not equal to 0
+## 95 percent confidence interval:
+##  4.910317 6.017601
+## sample estimates:
+## mean of x mean of y 
+##  80.41600  74.95204
+ +## Conclusion + +By running the tests and checking the effects of the outliers in the dataset and seeing that the results did not change, we can safely conclude that our interpretations stated before are correct. There is enough evidence to suggest that females in the United States live on average longer than males. We are 95% confident that they live longer than males by 5 to 6 years. \ No newline at end of file diff --git a/content/blog/manpandoc.md b/content/blog/manpandoc.md new file mode 100644 index 0000000..27f7341 --- /dev/null +++ b/content/blog/manpandoc.md @@ -0,0 +1,58 @@ +--- +title: "Man Pages with Pandoc" +date: 2019-11-07T21:42:08-05:00 +draft: false +--- + +[Ethan Martin](https://emar10.dev) recently showed off the Pandoc tool to me. In case you don't know, Pandoc is a swiss-army knife of markup languages. It allows you to easily convert from one markup language to another. + +This got me thinking my love for Markdown as the lowest common denominator for my notes. I can write markdown files for my website, for presentations, and output it into PDF and Word. Of course you don't get to have the fine control as you do with Latex, but with document classes, you can at least theme it any way you like! + +Now to focus this blog post, I do want to share one really cool feature I found out about Pandoc. It can create man pages. I thought of this as a great way to create documentation for a software project. I'll give you an example to kick things off. + +Note: The content is stolen from the `git` man page. + +```markdown +--- +title: git +section: 1 +header: Git Manual +--- + +# NAME + git - the stupid content tracker + +# SYNOPSIS + git `[--version] [--help]` + +# DESCRIPTION + Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals. + + See **gittutorial**(7) to get started, then see **giteveryday**(7) for a useful minimum set of commands. The **Git User’s Manual**[1] has a more in-depth introduction. + + After you mastered the basic concepts, you can come back to this page to learn what commands Git offers. You can learn more about individual Git commands with "git help command". **gitcli**(7) manual page gives you an overview of the command-line command syntax. + + A formatted and hyperlinked copy of the latest Git documentation can be viewed at **https://git.github.io/htmldocs/git.html**. + +# OPTIONS + --version + Prints the Git suite version that the git program came from. + + --help + Prints the synopsis and a list of the most commonly used commands. If the option --all or -a is given then all available commands are printed. If a Git command is named this option will bring up the manual page for that command. + + Other options are available to control how the manual page is displayed. See git-help(1) for more information, because git --help ... is converted internally into git help .... +``` + +Then execute + +```bash +pandoc -s -t man -o git.1 git.md +``` + +Here's what the command means: "Run `pandoc` on standalone mode converting `git.md` into a man page called `git.1`" + +To see the results run `man ./git.1` + +![1573183066061](/files/images/1573183066061.png) + diff --git a/content/blog/memoryerrorsgo.md b/content/blog/memoryerrorsgo.md new file mode 100644 index 0000000..72beb7c --- /dev/null +++ b/content/blog/memoryerrorsgo.md @@ -0,0 +1,20 @@ +--- +title: "Memory Errors in Go" +date: 2019-08-02T22:35:53-04:00 +draft: false +--- + +I enjoy playing with Valgrind. Sometimes I view it as a game to get rid of memory errors. When I wrote a go script, I noticed that I received a lot of memory errors. I decided to double check by writing a simple hello world program in Go. + +```go +package main +import "fmt" +func main() { + fmt.Println("Hello World") +} +``` +Running this then gives me a bunch of memory errors of the form `Invalid read of size 4`. + +Now this doesn't mean that the program is leaky. Valgrind does confirm that no leaks are possible. It then begs the question, does this type of memory error even matter? + +To avoid thinking about that I decided to play with [Rust](https://rust-lang.org) instead. \ No newline at end of file diff --git a/content/blog/mergerfs.md b/content/blog/mergerfs.md new file mode 100644 index 0000000..8745a3c --- /dev/null +++ b/content/blog/mergerfs.md @@ -0,0 +1,44 @@ +--- +title: "MergerFS" +date: 2020-01-14T23:10:17-05:00 +draft: false +images: [] +--- + +[MergerFS](https://github.com/trapexit/mergerfs) is a great filesystem for an expandable storage system in a homelab. Mostly since it allows you to add disks one at a time without having to, for example, resilver a ZFS pool. MergerFS won't be as efficient as a filesystem that stripes your data across disks, but in the case of a disk failure the disks unaffected will still have part of the data. + +[Plenty](https://blog.linuxserver.io/2017/06/24/the-perfect-media-server-2017/) of other [people](https://www.teknophiles.com/2018/02/19/disk-pooling-in-linux-with-mergerfs/) described MergerFS, so I'll keep this post simple. + +First install MergerFS, + +```bash +sudo apt install mergerfs +``` + +The way I have my drives in my homelab setup is to have `/mnt/data/N` where `N` is the number of the drive. + +Examples: `/mnt/data/1`, `/mnt/data/2`, `/mnt/data/3` + +This is mainly so that I can use wildcards to capture all the drives at once. + +Temporary mounting solution: + +```bash +sudo mergerfs -o defaults,allow_other,use_ino,fsname=data /mnt/data/\* $HOME/data +``` + +Permanent solution (Edit `/etc/fstab`) + +```bash +/mnt/data/* /home/user/data fuse.mergerfs defaults,allow_other,use_ino,fsname=data 0 0 +``` + +Quick summary of options passed + +| Option | Description | +| ----------- | ------------------------------------------------------------ | +| defaults | Shortcut for atomic_o_trunc, auto_cache, big_writes, default_permissions, splice_move, splice_read, splice_write | +| allow_other | Allows users beside the mergerfs owner to view the filesystem. | +| use_ino | MergerFS supplies inodes instead of libfuse | +| fsname | Name of the mount as shown in `df` and other tools | + diff --git a/content/blog/missingdata.md b/content/blog/missingdata.md new file mode 100644 index 0000000..afb020b --- /dev/null +++ b/content/blog/missingdata.md @@ -0,0 +1,14 @@ +--- +title: "Considerations with Missing Data" +date: 2019-05-22T23:18:45-04:00 +draft: true +--- + +Write something about "Missing Completely at Random" (MCAR) and maybe talk about a couple R packages for visualizing this.. + + + +Oh and also techniques for imputing + +- multiple imputation with chained equations +- random forest \ No newline at end of file diff --git a/content/blog/networkthroughput.md b/content/blog/networkthroughput.md new file mode 100644 index 0000000..e968925 --- /dev/null +++ b/content/blog/networkthroughput.md @@ -0,0 +1,27 @@ +--- +title: "Network Throughput Testing" +date: 2019-08-30T20:11:26-04:00 +draft: false +--- + +I ended up upgrading the wiring in my place to CAT7 recently and I wanted to see if there was a noticeable performance difference to my previous cabling. This blog post won't be a product comparison, but instead I'll show how you can do network throughput testing at your own location. + +There is a great package called `iperf`. It's in most repositories under Linux, and binaries for Windows and macOS exist as well. + +For a more in depth tutorial [check out this post from Linode](https://www.linode.com/docs/networking/diagnostics/install-iperf-to-diagnose-network-speed-in-linux/). + +*For the 5 second spiel...* + +One one machine, start the server + +```bash +iperf -s +``` + +On another machine connect to the server and begin testing the connection + +```bash +iperf -c 192.168.0.2 +``` + +You can also use the `-t` flag to specify the number of seconds you want to run the test for. diff --git a/content/blog/ngrok.md b/content/blog/ngrok.md new file mode 100644 index 0000000..fc42645 --- /dev/null +++ b/content/blog/ngrok.md @@ -0,0 +1,24 @@ +--- +title: "Ngrok" +date: 2019-11-20T20:56:19-05:00 +draft: false +--- + +Let's say you want to spin up a quick demo for a client and you don't want to use a VPS, and they can't access your laptop through the network. + +The easiest way I've known for the past few years to allow another person to access a specific port on your machine is through [ngrok](https://ngrok.com/). Ngrok is nice because not only do they offer a free plan, but they also offer paid plans. This means that you can trust that it'll at least be in business for a little while longer ;) + +## The Process + +You'll need to sign up for an account first. I was then going to write about some of the following steps, but `ngrok` has a really nice quad chart when you login + +![steps](/files/images/0932485094325.png) + +Just note that in step (3) you will actually have a random sequence of characters after `authtoken`. + +Something else you might want to know is how to enable TLS support, luckily that's a simple command line argument. + +```bash +ngrok http -bind-tls=true port +``` + diff --git a/content/blog/notimplemented.md b/content/blog/notimplemented.md new file mode 100644 index 0000000..a2f6454 --- /dev/null +++ b/content/blog/notimplemented.md @@ -0,0 +1,16 @@ +--- +title: "NotImplemented" +date: 2019-10-27T23:35:17-04:00 +draft: false +--- + +Let's say you overwrite the `__mul__` operator in a class in Python, but you don't want the function to be called for all kinds of input. You can specify the type by just returning `NotImplemented` for types you don't want. + +```python +class A: + def __mul__(self, x): + if not isinstance(x, A): + return NotImplemented + return someOperation() +``` + diff --git a/content/blog/ohmyzsh.md b/content/blog/ohmyzsh.md new file mode 100644 index 0000000..c7488e4 --- /dev/null +++ b/content/blog/ohmyzsh.md @@ -0,0 +1,45 @@ +--- +title: "Oh My Zsh" +date: 2019-07-21T08:45:03-04:00 +draft: false +--- + +Zsh is an extension of the sh that contains a lot more features than the default bash shell installed on most systems. + +For example, one of my new favorite features is being able to type in part of a command in your history and using the up-arrow to find it. + +For example: + +```bash +vim test.hi +``` + +Then typing `vim` and up-arrow will expand it to `vim test.hi`. Super handy when you have to type of long commands frequently. + +*Oh My Zsh* is a community project that superpowers zsh which allows you to easily add plugins and themes. The theme I'm currently using is [powerlevel10k](https://github.com/romkatv/powerlevel10k#oh-my-zsh) which is a custom theme. + +The list of plugins I have is: + +- git +- colored-man-pages +- colorize +- command-not-found +- cp +- rsync +- screen +- ssh-agent +- web-search +- docker +- node +- npm +- nvm +- gem +- ruby +- pip +- python +- pyenv +- virtualenv +- debian +- systemd +- sudo +- zsh-syntax-highlighting \ No newline at end of file diff --git a/content/blog/proofdef.md b/content/blog/proofdef.md new file mode 100644 index 0000000..2a863db --- /dev/null +++ b/content/blog/proofdef.md @@ -0,0 +1,17 @@ +--- +title: "Theorem Proving Definitions" +date: 2019-12-29T11:21:07-05:00 +draft: false +images: [] +--- + +When I look into a new field, sometimes I get confused by the whole new set of vocab terms I need to encounter. This post will serve to keep me straight with the terms involved in theorem proving. + +| Word | Definition | +| ------------ | ------------------------------------------------------------ | +| Modus Ponens | If $P$ implies $Q$ and $P$ is asserted to be true, then $Q$ must be true. | +| Complete | If every formula having the property can be derived using the system. (i.e The system does not miss a result) | +| Decidable | An effective method exists for deriving the correct answer in a finite time. | +| Sound | Every formula that can be proved in the system is logically valid with respect to the semantics of the system. (i.e The system does not produce a wrong result) | + +Hopefully, I'll come back and add more terms as I get confused. \ No newline at end of file diff --git a/content/blog/pythonpathhacks.md b/content/blog/pythonpathhacks.md new file mode 100644 index 0000000..baa9659 --- /dev/null +++ b/content/blog/pythonpathhacks.md @@ -0,0 +1,31 @@ +--- +title: "Python Path Hacks" +date: 2020-01-13T22:26:16-05:00 +draft: false +images: [] +--- + +There are two quick ways to hack together custom imports in Python. One is by using the `PYTHONPATH` environmental variable, and the other way is by using the `sys` module in Python. + +## Method 1: `PYTHONPATH` + +Before you call `python` set the environmental variable. + +```bash +PYTHONPATH=$PYTHONPATH:/other/path +``` + +Then you can call `python`. + +## Method 2: `sys` + +In the beginning of your Python script add the following code. + +```python +import sys +sys.path.append('/other/path') +``` + +## Remarks + +Of course this isn't the best way to add custom libraries to your Python scripts. Ideally, we would use `pip` to manage our dependencies. Perhaps a future blog post will cover this! \ No newline at end of file diff --git a/content/blog/pythonsymmetricgroups.md b/content/blog/pythonsymmetricgroups.md new file mode 100644 index 0000000..dc4db75 --- /dev/null +++ b/content/blog/pythonsymmetricgroups.md @@ -0,0 +1,109 @@ +--- +title: "Symmetric Groups in Python" +date: 2019-05-22T20:02:21-04:00 +draft: false +--- + +**Warning:** This post is meant for someone whose familiar with concepts of Abstract Algebra. + +## Refresher + +### Definitions + +An **operation** on a set is a calculation that maps one element in a set onto another element of the set. + +A **group** in mathematics is a set and an operation that follows the three properties: + +- There exists an identity element. +- The operation is associative. +- For every element, there exists an inverse of that element in the set. + +**Symmetric Groups** are groups whose elements are all bijections from the set onto itself and operation which is composition of functions. + +### Example + +Let's look at the group $\mathbb{Z}_3$. Here is an example of an element of its symmetric group. +$$ +\begin{pmatrix} +0 & 1 & 2 \\ +1 & 2 & 0 +\end{pmatrix} +$$ +This element maps $0 \rightarrow 1$, $1 \rightarrow 2$, and $2 \rightarrow 0$. + +A good way to check if something similar to the above is an element of a symmetric group is pay attention to the second row. Make sure that it only contains the elements of the set you care about (ex: $\mathbb{Z}_3$) and that there are no repeats. + +Let's look at an example of composing two elements from this symmetric group. +$$ +\begin{pmatrix} +0 & 1 & 2 \\ +1 & 2 & 0 +\end{pmatrix} +\circ +\begin{pmatrix} +0 & 1 & 2 \\ +0 & 2 & 1 \\ +\end{pmatrix} += +\begin{pmatrix} +0 & 1 & 2 \\ +1 & 0 & 2 \\ +\end{pmatrix} +$$ +The main thing to remember here is that you must compose from right to left. + +$0 \rightarrow 0$ and then $0 \rightarrow 1$, so ultimately $0 \rightarrow 1$. + +$1 \rightarrow 2$ and $2 \rightarrow 0$, so ultimately $1 \rightarrow 0$. + +$2 \rightarrow 1$ and $1 \rightarrow 2$, so ultimately $2 \rightarrow 2$. + +### Finding Inverses + +Finding the inverse is simple, since all you need to do is flip the two rows and sort it again. +$$ +\begin{pmatrix} +0 & 1 & 2 \\ +1 & 2 & 0 +\end{pmatrix}^{-1} = +\begin{pmatrix} +1 & 2 & 0 \\ +0 & 1 & 2 +\end{pmatrix} = +\begin{pmatrix} +0 & 1 & 2 \\ +2 & 0 & 1 +\end{pmatrix} +$$ + + ### Code Implementation + +For Abstract Algebra homework, there was a lot of compositions of these symmetric elements. Sadly, I get pretty lazy doing these by hand for many hours. So like any Computer Scientist, I created a simple script in Python to help me compute these. + +The code is located in [this gist](https://gist.github.com/Brandon-Rozek/adf9e1e64e2fbfcd3f8d3bc5da9322bf). + +#### Basic Usage + +`SymmetricElement` takes in the second row of the matrices we were playing with. You can find the inverse with `element.inverse()` and you can compose two symmetric elements together with the `*` operation. + +```python +SymmetricElement(1,2,3) +# array([[1., 2., 3.], +# [1., 2., 3.]]) +``` + +```python +SymmetricElement(1,2,3) * SymmetricElement(2,1,3) +#array([[1., 2., 3.], +# [2., 1., 3.]]) + +``` + +```python +SymmetricElement(1,2,3).inverse() +#array([[1., 2., 3.], +# [1., 2., 3.]]) +``` + + + diff --git a/content/blog/pythontyping.md b/content/blog/pythontyping.md new file mode 100644 index 0000000..e566c1e --- /dev/null +++ b/content/blog/pythontyping.md @@ -0,0 +1,14 @@ +--- +title: "Python Typing" +date: 2019-10-28T00:12:34-04:00 +draft: false +--- + +There's a typing module built right into Python that you can use on your applications. Sobolevn write a great [blog post](https://sobolevn.me/2019/01/simple-dependent-types-in-python) about it. One thing that threw me off at first is that if you add type annotations and then run python like you normally would, it would act as if the annotations weren't there. + +Why use type annotations then? + +1. It enhances your internal docs. VS Code and other editors pick this up and show it to the user in their IDE. +2. You can use `mypy` to perform type checking for you. + +I go back and forth with type checking in Python, but I do think that forcing yourself to follow type safety makes you a better programmer. \ No newline at end of file diff --git a/content/blog/quickstoragesetup.md b/content/blog/quickstoragesetup.md new file mode 100644 index 0000000..8b81411 --- /dev/null +++ b/content/blog/quickstoragesetup.md @@ -0,0 +1,71 @@ +--- +title: "Quickly Setting up a Storage Device" +date: 2020-01-12T21:43:26-05:00 +draft: false +images: [] +--- + +This post exists mostly to aid myself for when I buy new drives for my home server. It's a quick and easy way to create an ext4 filesystem over the entire drive. + +To go through this post, you'll need to know the name of your drive. + +```bash +sudo fdisk -l +``` + +or + +```bash +lsblk +``` + +The drive is most likely one of the larger devices with no partitions set. It'll likely be of the format `/dev/sdX`. + +To begin, we'll have to set the label. Here we'll use `gpt`. + +```bash +sudo parted /dev/sdX mklabel gpt +``` + +Then we can create a primary partition formatted with ext4 covering the entire device. + +```bash +sudo parted -a opt /dev/sdX mkpart primary ext4 0% 100% +``` + +Now we can let `ext4` format the drive, + +```bash +sudo mkfs.ext4 /dev/sdX +``` + +I like to set up my mount points to be `/mnt/data/N` where N is the number of the drive I'm working with. + +```bash +sudo mkdir /mnt/data/N +``` + +To temporarily mount it, just to make sure it works you can run + +```bash +sudo mount /dev/sdX /mnt/data/N +``` + +You can unmount it with `umount` + +```bash +sudo umount /dev/sdX +``` + +When you're ready to make it permanent, we'll have to edit the `/etc/fstab` file. We should note the drive by its UUID so that it's not dependent on the slot the hard drive sits in. You can find it by running this command + +```bash +lsblk -o UUID /dev/sdX1 +``` + +Now you can append your `/etc/fstab` with the following: + +```bash +UUID=uuid-here /mnt/data/N ext4 defaults 0 0 +``` + diff --git a/content/blog/robustdd.md b/content/blog/robustdd.md new file mode 100644 index 0000000..b8038ef --- /dev/null +++ b/content/blog/robustdd.md @@ -0,0 +1,33 @@ +--- +title: "Robustdd" +date: 2019-09-27T22:45:56-04:00 +draft: false +--- + +This blog post is going to assume that we're writing to `/dev/sdX`. Please change this to whatever disk you're actually trying to write to. I bear no responsibility if you accidentally write to your OS drives. + +Make sure the disk you wish to write to is unmounted. + +```bash +sudo umount /dev/sdX +``` + +For good measure check `lsblk`.... + +Then perform the writing operation + +```bash +sudo dd bs=4M if=/path/to/distro.iso of=/dev/sdX conv=fdatasync status=progress +``` + +`fdatasync` will wait until the data is physically written into the drive before finishing. + +Once that operation is done we can check to see if it is performed properly. This step will only work for ISOs that have prepared a file similar to `md5sum.txt` that Ubuntu provides.... + +```bash +sudo mount /dev/sdX /mnt +cd /mnt +md5sum -c md5sum.txt +``` + +Hopefully you'll see all `OK` and we're good to go! diff --git a/content/blog/rsa.md b/content/blog/rsa.md new file mode 100644 index 0000000..4f3ec5a --- /dev/null +++ b/content/blog/rsa.md @@ -0,0 +1,72 @@ +--- +title: RSA Cryptography +date: 2019-12-10T22:15:21-05:00 +draft: false +images: [] +--- + +# Introduction + +Why do we need Cryptography? Well let's say Bob is purchasing things from Alice over the internet. He wants to give Alice his credit card details to complete his transaction, but he feels uncomfortable with the thought that others can possibly read it as well. RSA is a cryptosystem that underlies HTTPS, and this gives Bob a sense of security that only Alice can see his message. + +The journey of RSA starts in 1976 when Whitfield Diffie and Martin Hellman published a framework describing an asymmetric public-private key cryptosystem through four key steps: + +1. Key Generation +2. Key Distribution +3. Encryption with one-way function (using a public key) +4. Decryption (using a private key) + +They left the one-way function undefined, making it an open problem for the community. Ron **R**ivest, Adi **S**hamir, and Leonard **A**dleman at MIT took up this challenge. Rivest and Shamir were Computer Scientists trying to come up with this function while Adleman was the mathematician tasked with finding flaws in their discoveries. After working together to develop the RSA cryptosystem in 1977, Rivest, Shamir, and Adleman went on to found the organization RSA Data Security in 1982. + +# RSA Algorithm + +In this section, we'll look at the RSA algorithm through the lens of the four steps listed in the previous section. + +#### Key Generation + +Alice needs to generate public and private keys through the following method: + +1. Choose two distinct prime integers $p$ and $q$. +2. Compute $n = pq$. The integer $n$ will be later released as part of the *public key*. +3. Calculate $\phi(n)$ which by the Euler's Totient Product of Primes property is $(p - 1)(q - 1)$. +4. Choose $e \in \mathbb{Z}$ such that $e$ and $\phi(n)$ are relatively prime. The integer $e$ will also be released as part of the *public key*. +5. Calculate $d$, the multiplicative inverse of $e$ modulo $\phi(n)$. The integer $d$ will be kept secret as the *private key*. + +#### Key Distribution + +For Bob to send a message to Alice, he will need to know Alice's public key $n$ and $e$. Bob, however, does not need to know Alice's prime integers $p$ and $q$ that divide $n$. Nor does he need to know the private key $d$. + +#### Encryption + +Let $m \in \mathbb{Z}_n$ be the message that Bob wants to send. Bob calculates this number from his message using an agreed-upon reversible algorithm. The ciphertext or encrypted block $c$ is computed by, $c \equiv m^e$ (mod $n$). Bob then sends the ciphertext to Alice. + +#### Decryption + +Alice receives this ciphertext $c$ from Bob and then can recover the original message $m$ by computing $c^d$ modulo $n$. How is this possible? Well recall that $c^d \equiv (m^e)^d$. Then, $c^d \equiv m^{ed}$ by exponent rules. Recall that $e$ and $d$ are multiplicative inverses modulo $\phi(n)$. Therefore by definition, $ed = 1 + \phi(m)t$ for some $t \in \mathbb{Z}$. Then, + +\begin{align*} +c^d &\equiv m^{1 + \phi(n)t} \\\\ + &\equiv m(m^{\phi(n)})^t +\end{align*} + +Well since $n$ is prime, by Euler's Theorem $m^{\phi(n)} \equiv 1$ modulo $n$. Thus, $c^d \equiv m \cdot 1^t \equiv m$ modulo $n$. Through this short proof, we can see that Alice successfully retrieves Bob's message $m$ just by raising the ciphertext $c$ to the power of the private key $d$. + +## Example + +Let's run through a short example of this algorithm with small integers. Let $p = 3, q = 5$. Then $n = pq = 15$. We then calculate $\phi(n) = \phi(p)\phi(q) = 2(4) = 8$. An integer $e$ that is relatively prime to $\phi(n)$ is $11$. Finally we compute the inverse of $e$ modulo $\phi(n)$. + +\begin{align*} +11d &\equiv 1 \text{ (mod $8$) } \\\\ +11d &\equiv 33 \text{ (mod $8$)} \\\\ +d &\equiv 3 \text{ (mod $8$)} +\end{align*} + + +Alice then gives Bob the integers $n = 15$ and $e = 11$. Bob can then encode his message (say $m = 12$) by raising $m$ to the power of $e$. Thus, $c = m^e = 12^{11} = 743008370688 \equiv 3$ modulo 15. Alice can then recover $m = 12$ by raising $c = 3$ to the power of her private key $d$. $m \equiv c^d \equiv 3^3 \equiv 27 \equiv 12$ modulo $15$. + + +# Discussion + +Well if it's this simple to calculate, why is it secure? It is actually extremely difficult to factor a large prime number $n$. If $n$ can be factored into $p$ and $q$, then it is easy to compute $d \equiv e^{-1}$ modulo $\phi(pq)$. It is also really hard to efficiently solve for $m$ in the congruence $c \equiv m^e$ modulo $n$. RSA Laboratories on March 1991 issued a challenge tasking the public to calculate prime factors of $n$ (called RSA numbers) of increasing digits. They offered a cash prize of up to \$200,000 for solving RSA-2048 which is a 617 digit long number. As of the time of the presentation, the largest factored RSA number was RSA-768 (768 bits or 232 decimal digits) which was calculated over the span of two years. As of the time of this writing, towards the end of this year (2019) the largest known factored RSA number is actually RSA-240 (795 bits or 240 decimal digits). Currently the National Institute of Standards and Technology (NIST) recommends the use of 2048-bit keys for use in RSA. So for the time being, our communications are safe. + + diff --git a/content/blog/rsynckey.md b/content/blog/rsynckey.md new file mode 100644 index 0000000..9b9127c --- /dev/null +++ b/content/blog/rsynckey.md @@ -0,0 +1,28 @@ +--- +title: "Rsync with a Different Key" +date: 2019-07-06T09:20:05-04:00 +draft: false +--- + +To use Rsync with a different key, follow the command structure below. + +```bash +rsync -e "ssh -i $HOME/.ssh/key" user@hostname:/from/dir/ /to/dir/ +``` + +Though for syncing my local website to my VPS, I usually like having more options with my rsync command + +```bash +rsync -Paz --delete -e "ssh -i $HOME/.ssh/key" user@hostname:/from/dir/ /to/dir/ +``` + +Quick option definitions (from man page) + +| Option | Description | +| -------------- | ------------------------------------------------------------ | +| -e | Allows you to override the default shell used as the transport for rsync. Command line options are permitted after the command name. | +| -a, --archive | This is equivalent to -rlptgoD. It is a quick way of saying you want recursion and want to preserve almost everything (with -H being a notable omission). The only exception to the above equivalence is when --files-from is specified, in which case -r is not implied.
Note that -a does not preserve hardlinks, because finding multiply-linked files is expensive. You must separately specify -H. | +| -P | Equivalent to --partial --progress. Its purpose is to make it much easier to specify these two options for a long transfer that may be interrupted. | +| -z, --compress | Compress file data during the transfer | +| --delete | Delete extraneous files from dest dirs | + diff --git a/content/blog/scrcpy.md b/content/blog/scrcpy.md new file mode 100644 index 0000000..7f24d5b --- /dev/null +++ b/content/blog/scrcpy.md @@ -0,0 +1,27 @@ +--- +title: "Scrcpy" +date: 2020-01-09T21:36:30-05:00 +draft: false +images: [] +--- + +With [Scrcpy](https://github.com/Genymobile/scrcpy) you can control an Android device remotely! + +![1578623897330](/files/images/1578623897330.png) + +The `README` on the Github page has all the information you need though it boils down to a few simple steps. + +1. Install `scrcpy`. +```bash +sudo snap install scrcpy +``` +2. [Enable adb debugging](https://developer.android.com/studio/command-line/adb.html#Enabling) on your device +3. (Optional for remote capability) Enable adb over TCP/IP on your device +```bash +adb tcpip 5555 +``` +4. (Optional Continued) Connect to the device + ```bash + adb connect DEVICE_IP:5555 + ``` + 5. Run `scrcpy` \ No newline at end of file diff --git a/content/blog/screwuppresentations.md b/content/blog/screwuppresentations.md new file mode 100644 index 0000000..f2136c0 --- /dev/null +++ b/content/blog/screwuppresentations.md @@ -0,0 +1,124 @@ +--- +title: "Notes on '13 Ways Designers Screw Up Client Presentations'" +date: 2019-05-21T22:20:14-04:00 +draft: false +--- + +I watched a great talk by [Mike Monteiro](http://mikemonteiro.com/) recently called [13 Ways Designers Screw Up Client Presentations](https://www.youtube.com/watch?v=IXXKqwrEql4). You should really watch the talk but this post is just a quick summary of the points he got across in the presentation. + +## Intro + +You need to sell your work! Great work is worth nothing if you can't persuade the client it is good. + +Don't leave the selling to other people. That is your job. Every decision you make is backed by some data or experience. If you're not there, then you lose context and won't be there for feedback. + +On to the mistakes.... + +## 1. You are not there to be the client's friend + +You are there to solve the client's goal. Happiness is the side-effect of good design, not a goal. + +You are there to convince the client not to go down avenues that run counter to their goals. That's what they hired you for. You need to present yourself as the expert that they believed they hired. + +For example, your doctor needs to tell you if you have a cracked tooth. Do you think that they would hide this information from you because it might hurt your feelings? No, because it is their job to tell you this information. + +## 2. Not getting off your ass + +It should be obvious when you enter the room, who is in charge of the presentation. + +Confidence isn't about you feeling better, it is about your client feeling better. + +## 3. Starting with an apology + +Every time you apologize for something you are freaking the client out. No matter how much you hoped to present at the presentation, by the time you get to that room, you have the perfect amount of stuff. + +If you don't feel like the work is up to spec, cancel the presentation. Do not have a presentation of work you cannot stand behind. It is better to cancel than waste people's time. You can get away with this exactly once during a project. + +Your client probably works for somebody higher up, the minute you start apologizing to them, they imagine themselves apologizing to their boss! + +## 4. Not Setting the Stage Properly + +You have gathered busy people together, they probably have other things they can be doing, so let them know what this presentation is for. + +Let them know why they are a necessary and important part of this conversation. + +You need to address these two things at the beginning of the presentation + +1. Why are we here? + 1. Let them know what their roles are, why they are here, what you are going to show, and what you need from them. +2. When can we leave? + 1. Let them know what it takes for the goal of the meeting to be met. The minute you get it, the meeting is over. Never give a client time to unmake a decision, especially a decision in your favor. + +Once you have gotten what you need, keep quiet. Everything you do beyond that threatens to undo the victory you just got. + +## 5. Giving the Real Estate Tour + +You don't sell a house by talking about the sheetrock. You sell it by getting a buyer to picture themselves in the neighborhood, by picturing the kids in the playground, etc. + +You sell the benefits of the work, and you sell how the work matches the project goals. + +Every decision on that page should be made with the benefit of data and good research, but people make decisions based on stories. + +## 6. Taking Notes + +Find somebody else to take the notes. You are giving the presentation. + +## 7. Reading a Script + +You need to convince the client that you are excited about the product. + +"Without promotion something terrible happens.... Nothing" - PT. Barnum + +## 8. Getting Defensive + +You are not your work, and your work is not you. + +Your work is a product made to meet a client's goals. The client is free to criticize the work and is free to tell you whether they believe it has met the goals or not. You are free to present evidence to the contrary but not get hurt by the criticism. + +When the client starts critiquing the work listen to what they're saying, don't feel like you have to defend everything they're saying right then and there. You also don't have to promise them anything then and there, sometimes it's best to sit on it for a while. + +When a client is giving you feedback it is a great time to keep your mouth shut. + +## 9. Mentioning Typefaces + +Clients don't care about typefaces. You don't really want their input on this. Clients are uncomfortable in your field. The more you dive into these things, the more uncomfortable they're going to get. And it's going to look like you're inviting them to do your job for them. + +Stop asking for permission to do a job you were hired for. + +Their comfort zone is their business needs, which is great since you are never going to be an expert on their domain. Talk about your work in terms of their business and needs. + +## 10. Talking about how hard you worked + +You're not getting a grade on effort. + +If you do the work right, it will look like it was effortless. + +## 11. Reacting to questions as change requests + +"Why is this blue?" + +"Oh I can change it." + +Sometimes the client just has a question! They're just looking for your reasoning. + +## 12. Not guiding the feedback loop + +Most clients have no idea what kind of feedback you are looking for. They are not trained in your work. Anything that helps you do your job is part of your job. Know what you want before calling the presentation. + +Some suggestions: + +1. How well does this reflect your brand? +2. How well does this reflect your users' needs as we discussed in the research? +3. How well does this reflect your ad strategy? + +They're not going to give it to you unless you explicitly ask for it. + +## 13. Asking "Do you like it?" + +If it had a like button on it would you push it? + +All the work you and your team did went down the drain! The client is no longer looking at you as an expert. + +Every decision on the project has been made with the benefit of expertise and data and you just uttered the most subjective phrase. + +If you want to make your client's happy, make them successful. \ No newline at end of file diff --git a/content/blog/shutdownafterjob.md b/content/blog/shutdownafterjob.md new file mode 100644 index 0000000..4899a8f --- /dev/null +++ b/content/blog/shutdownafterjob.md @@ -0,0 +1,22 @@ +--- +title: "Shutdown After Job" +date: 2019-08-30T20:43:56-04:00 +draft: false +--- + +I'm back to running longer jobs as part of my research. If I run a task overnight, I want to conserve energy and not keep it running after I finish. I suppose this would also apply to cloud billing, you want it to do the job and then stop. + +This technique will require you to have sudo privileges on the machine. + +1. Change user to root. + +```bash +sudo su +``` + +2. Run job as regular user, write output to file, and then poweroff. + +```bash +su -u user task > output.txt && chown user:user output.txt && poweroff +``` + diff --git a/content/blog/simulators.md b/content/blog/simulators.md new file mode 100644 index 0000000..a3958e6 --- /dev/null +++ b/content/blog/simulators.md @@ -0,0 +1,15 @@ +--- +title: "Simulators" +date: 2019-07-01T22:22:29-04:00 +draft: false +--- + +Part of my job involves integrating multiple different sensors together to make a cohesive product. One thing that I appreciate about my current team, is the rich set of tooling built around the project. I am definitely learning a lot from this project. One thing I wanted to share was the use of *simulators*. + +Now since we're working with sensor data, it doesn't always make sense to need to be connected to a whole system. There's also the additional hassle of dealing with safety and working outside. So in order to do some programming and still be at ease that we didn't break anything, we make heavy use of simulators. + +Example: Have a GPS hooked up to your system? Well with a tool you can make waypoints and generate a file which you then feed in as a fake GPS device! + +Now when I say fake device, I don't mean I'm actually emulating the device on the machine. It's easier to have your device interfacers publish to the local network and have your other parts of the application subscribe to it. So in this case, you will just need to produce those messages directly. + +So in conclusion, I think this pattern will work well for my personal projects. It helps keep your code modular and easily testable! diff --git a/content/blog/sshconfig.md b/content/blog/sshconfig.md new file mode 100644 index 0000000..b1cf506 --- /dev/null +++ b/content/blog/sshconfig.md @@ -0,0 +1,16 @@ +--- +title: "SSH Config" +date: 2019-09-27T22:46:39-04:00 +draft: false +--- + +Have you ever gone through the hassle of having multiple public/private keys for accessing your remote servers? Before recently, I used to specify the identity file in all my transactions `ssh -I ~/.ssh/private_key user@host` but no longer! I discovered you can add the following to your `~/.ssh/config` to specify which key you want to use! + +``` +Host someaddress + Hostname someaddress + user usernameonserver + IdentityFile ~/.ssh/private_key +``` + +Of course you can add multiple of these entries in that file so that you can `ssh` without having to worry about explicitly using keys. \ No newline at end of file diff --git a/content/blog/sshlocalportforwarding.md b/content/blog/sshlocalportforwarding.md new file mode 100644 index 0000000..9bf4c2d --- /dev/null +++ b/content/blog/sshlocalportforwarding.md @@ -0,0 +1,19 @@ +--- +title: "SSH Local Port Forwarding" +date: 2019-08-06T16:50:00-04:00 +draft: false +--- + +There are some services that I don't want to run all the time which makes me not want to open a port for it. One good example of this is [Jupyter Notebooks](https://jupyter.org/). Therefore, what I sometimes do is run it locally and forward the port so that another machine can access it. + +Example command: + +```bash +ssh -L 8888:localhost:8888 -N 192.168.0.2 +``` + +The `-L` flag allows you to specify the `localsocket:host:remotesocket`. + +`-N` makes it so that it doesn't execute any additional commands + +Then finally you put the address of the machine you wish to connect to. diff --git a/content/blog/systemdstartup.md b/content/blog/systemdstartup.md new file mode 100644 index 0000000..3a783b4 --- /dev/null +++ b/content/blog/systemdstartup.md @@ -0,0 +1,23 @@ +--- +title: "Analyzing Startup Times with Systemd" +date: 2019-12-26T22:52:59-05:00 +draft: false +images: [] +--- + +Startup times feeling slow? Check to see if there are any uneeded services slowing you down! + +To see how long it takes to bootup + +```bash +systemd-analyze +``` + +To see the length of time each service took to initialize + +```bash +systemd-analyze blame +``` + +Then you can `disable` any services that you don't need. + diff --git a/content/blog/systemdwithpythonenvs.md b/content/blog/systemdwithpythonenvs.md new file mode 100644 index 0000000..80e77ca --- /dev/null +++ b/content/blog/systemdwithpythonenvs.md @@ -0,0 +1,29 @@ +--- +title: "Systemd with Python environments" +date: 2019-08-25T20:04:20-04:00 +draft: false +--- + +It took me some time to realize why I couldn't start a project during startup. I then realized that it was because I was using a python virtual environment and didn't tell systemd about it. + +Here's how you can do so... + +```yaml +[Unit] +Description=Start Service +# After=network.target # If you want a python webserver... + +[Service] +Type=Simple +User=brandon +WorkingDirectory=/home/brandon/Development +ExecStart=/bin/sh -c ". /home/brandon/Development/pythonenv/bin/activate; /home/brandon/Development/start" + +[Install] +WantedBy=multi-user.target +``` + + + + + diff --git a/content/blog/tempresolve.md b/content/blog/tempresolve.md new file mode 100644 index 0000000..2fa1a7f --- /dev/null +++ b/content/blog/tempresolve.md @@ -0,0 +1,24 @@ +--- +title: "Temporarily Resolving Hostnames" +date: 2020-01-04T21:26:16-05:00 +draft: false +images: [] +--- + +Let's say that we're testing a webserver where the pages served depended on a domain that you don't own. The most common way I know to test this is to modify your `/etc/hosts` file to contain the hostname and ip address you want to map it to. + +``` +192.168.1.2 custom.domain +``` + +I've recently discovered that the command line utility `curl` has a quick and easy option to forge the hostname of a request. + +```bash +curl --resolve domain:port:ipaddr url +``` + +There are also browser extensions that you can use such as [LiveHosts](https://github.com/Aioros/livehosts) to get around this as well. This post isn't entirely useful when talking about permanent services. + +If this is going to be a publicly facing service, then you should just set the records of your domain name to point to the server. + +If it's a non-public routable service, then perhaps try looking into setting up your own private [dns server](https://brandonrozek.com/blog/coredns/). \ No newline at end of file diff --git a/content/blog/tensorboard.md b/content/blog/tensorboard.md new file mode 100644 index 0000000..749ae19 --- /dev/null +++ b/content/blog/tensorboard.md @@ -0,0 +1,6 @@ +--- +title: "Tensorboard" +date: 2019-05-26T19:04:47-04:00 +draft: true +--- + diff --git a/content/blog/togglingxinput.md b/content/blog/togglingxinput.md new file mode 100644 index 0000000..65c9439 --- /dev/null +++ b/content/blog/togglingxinput.md @@ -0,0 +1,30 @@ +--- +title: "Toggling X Input" +date: 2020-01-07T20:46:32-05:00 +draft: false +images: [] +--- + +On X, we can easily enable or disable input devices using the `xinput` command. This is a great use case when you're tired of accidentally hitting the red Thinkpad nub or having your palm be recognized when drawing with a pen. + +Running the `xinput` command performs the action temporarily. Your default settings will be restored upon a reboot. + +To list `xinput` devices run: + +```bash +xinput +``` + +To disable a device: + +```bash +xinput disable [id] +``` + +To enable a device: + +```bash +xinput enable [id] +``` + +The ids are listed when you list the devices. \ No newline at end of file diff --git a/content/blog/traefiknginx.md b/content/blog/traefiknginx.md new file mode 100644 index 0000000..4c51c73 --- /dev/null +++ b/content/blog/traefiknginx.md @@ -0,0 +1,70 @@ +--- +title: "Traefik & Nginx" +date: 2019-12-16T19:55:47-05:00 +draft: false +images: [] +--- + +I've been enjoying Traefik for its auto-discovery of containers. The only problem is that for a couple containers such as Plex and HomeAssistant I have host networking enabled. This usually results in Traefik failing to forward the traffic properly. + +Having more fine grained control is exactly what Nginx is for! I don't want to switch my whole setup to Nginx since that would be a lot of configuration files for every docker container. But I think having configuration files for containers that use host networking is manageable. + +In your docker-compose file first make sure that Traefik is disabled for containers that use host networking by adding the label `traefik.enable=false` + +```yaml + homeassistant: + image: homeassistant/home-assistant + container_name: homeassistant + hostname: homeassistant + network_mode: host + environment: + - PUID=1000 + - PGID=1000 + volumes: + - /Volumes/homeassistant/config:/config + restart: always + labels: + - traefik.enable=false +``` + +Then add a new section for `nginx` adding the domains that you wish it to manage in the labels + +```yaml +nginx: + image: linuxserver/nginx + container_name: nginx + environment: + - PUID=1000 + - PGID=1000 + volumes: + - /Volumes/nginx/config:/config + restart: always + labels: + - traefik.http.routers.my-container.rule=Host(`plex.example.com`,`homeassistant.example.com`) +``` + +Now on the host system add the configuration files for nginx to consume. Example: + +```nginx +server { + listen 80; + listen [::]:80; + + server_name plex.example.com; + + location / { + proxy_pass http://homelanip:32400; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } +} +``` + +Similarly add a configuration file for `homeassistant` or any other service you have. + +Now for this example, the subdomains `plex.example.com` and `homeassistant.example.com` are managed by Nginx. + +To finish it off, `docker-compose start nginx`. diff --git a/content/blog/unattended-upgrades.md b/content/blog/unattended-upgrades.md new file mode 100644 index 0000000..01eeaaf --- /dev/null +++ b/content/blog/unattended-upgrades.md @@ -0,0 +1,11 @@ +--- +title: "Unattended Upgrades" +date: 2019-05-26T12:52:03-04:00 +draft: false +--- + +I'm a big believer of reducing maintenance. One of the things that I didn't bother setting up before but should've is *unattended upgrades*. The benefits of this is that you don't have to repeatedly log into your sever to upgrade your system. + +Why bother managing your own server in the first place? Well with a virtualized system you can set up any type of application that you like. You're not limited to only hosting static sites or whatever applications the C-Panel instance allows. + +Now there's no need for me to reiterate what's been done before, so here's a [useful post from libre-software](https://libre-software.net/ubuntu-automatic-updates/) describing how to set it up so that a Ubuntu server updates itself automatically. \ No newline at end of file diff --git a/content/blog/usbredirection.md b/content/blog/usbredirection.md new file mode 100644 index 0000000..de989b5 --- /dev/null +++ b/content/blog/usbredirection.md @@ -0,0 +1,9 @@ +--- +title: "Wacom and USB Redirection in Virtual Machines" +date: 2019-05-24T22:15:56-04:00 +draft: false +--- + +[Virt-Manager](https://virt-manager.org/) is a great tool for managing virtual machines under Linux. Today I learned of [Spice USB redirection](https://blog.wikichoon.com/2014/04/spice-usb-redirection-in-virt-manager.html). Essentially it allows you to switch USB devices from the host to the virtualized environment. This came in handy when I noticed that the graphics tablet device was not able to do pressure sensitivity on the Windows guest. + +To achieve this goal, I removed the graphics tablet hardware device and manually redirected that USB device to the guest. I then remembered to install the [Wacom drivers](https://www.wacom.com/en-us/support/product-support/drivers) for the Windows VM. \ No newline at end of file diff --git a/content/blog/videosandgifs.md b/content/blog/videosandgifs.md new file mode 100644 index 0000000..00a604e --- /dev/null +++ b/content/blog/videosandgifs.md @@ -0,0 +1,22 @@ +--- +title: "Videos and GIFs" +date: 2019-12-04T10:13:35-05:00 +draft: false +images: [] +--- + +I like using GIFs in Google Slides because it doesn't require any interaction to start playing right away. Therefore, I looked at a couple resources to add a GIF from a video into my presentation. Of course this is all using one of my favorite terminal tools `ffmpeg`. + +First of all, I wanted to include a video of a bot playing Pong. The video was a little long, so I decided speed it up for a more time-lapse type feel. + +[From the FFMPEG website](https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video): To 10x the speed `ffmpeg -i input.mkv -filter:v "setpts=0.1*PTS" output.mkv` + +You just need to replace the `0.1` with the appropriate decimal number to change the speed. + +Giphy has a great [writeup](https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/) describing the commands to use in order to make your GIF look nice. + +```bash +ffmpeg -i inputvideo.mp4 -filter_complex "[0:v] palettegen" palette.png +ffmpeg -i inputvideo.mp4 -i palette.png -filter_complex "[0:v][1:v] paletteuse" output.gif +``` + diff --git a/content/blog/virtualdisks.md b/content/blog/virtualdisks.md new file mode 100644 index 0000000..e200e75 --- /dev/null +++ b/content/blog/virtualdisks.md @@ -0,0 +1,84 @@ +--- +title: "Virtual Disks" +date: 2020-01-06T22:26:58-05:00 +draft: false +images: [] +--- + +Have you wanted to [play with ZFS](https://wiki.archlinux.org/index.php/ZFS/Virtual_disks) or any other filesystem without creating a dedicated partition or device? We can do this through virtual disks! + +First, we need to create a [sparse file](https://en.wikipedia.org/wiki/Sparse_file) called `scratch.img` with some max capacity. Let's say 2G. + +```bash +truncate -s 2G $HOME/scratch.img +``` + +Now the file is only sparse, if your filesystem supports it. To see, run `du -sh $HOME/scratch.img`. If it says that the size is `0` then your filesystem supports sparse files. Otherwise it does not. + +Then, we can format the file with any filesystem we will like. One popular tool is `mkfs` which depending on your operating system can support [`bfs`](https://en.wikipedia.org/wiki/Be_File_System), [`cramfs`](https://en.wikipedia.org/wiki/Cramfs), [`ext2`](https://en.wikipedia.org/wiki/Ext2), [`ext3`](https://en.wikipedia.org/wiki/Ext3), [`ext4`](https://en.wikipedia.org/wiki/Ext4), [`fat`](https://en.wikipedia.org/wiki/File_Allocation_Table), [`minix`](https://en.wikipedia.org/wiki/MINIX_file_system), `msdos`, [`ntfs`](https://en.wikipedia.org/wiki/NTFS), [`vfat`](https://en.wikipedia.org/wiki/File_Allocation_Table#VFAT), [`reiserfs`](https://en.wikipedia.org/wiki/ReiserFS), etc. + +To format with `ext4`, + +```bash +mkfs -t ext4 $HOME/scratch.img +``` + +Then we can create the mount-point `/mnt/scratch` and mount `scratch.img` to it. + +```bash +sudo mkdir /mnt/scratch +sudo mount -t auto -o loop $HOME/scratch.img /mnt/scratch +``` + +With this, we now have a mounted `ext4` filesystem on `/mnt/scratch`. `cd` into it and have a blast! + +## Resizing the Virtual Disk + +To resize the virtual disk, we will first need to unmount the virtual disk so we don't create inconsistencies. + +```bash +sudo umount /mnt/scratch +``` + +Now we can extend or shrink the drive with `truncate`. + +Extend by 1G: `truncate -s +1G $HOME/scratch.img` + +Shrink by 1G: `truncate -s -1G $HOME/scratch.img` + +Check the filesystem to make sure that no inconsistencies occured. With `ext(2/3/4)` we can do this with the `e2fsck` command. + +```bash +e2fsck $HOME/scratch.img +``` + +Then we need to tell the filesystem to resize itself. For `ext(2/3/4)` you can do this with the `resize2fs` command. + +```bash +resize2fs $HOME/scratch.img +``` + +Now the virtual disk is successfully resized! We can mount it back with the previous mount command. + +```bash +sudo mount -t auto -o loop $HOME/scratch.img /mnt/scratch +``` + +## Removing the Virtual Disk + +To remove the virtual disk, we first need to unmount the virtual drive + +```bash +sudo umount /mnt/scratch +``` + +Then we can remove the mount-point and file. + +```bash +sudo rm -r /mnt/scratch +rm $HOME/scratch.img +``` + +## Conclusion + +With virtual disks we can experiment with different types of filesystems and perhaps try out snapshotting in supported filesystems. If we create virtual disks on [`tmpfs` ](/blog/lxdtmpfs/), then we can have a super fast file system as well! \ No newline at end of file diff --git a/content/blog/virtualenv.md b/content/blog/virtualenv.md new file mode 100644 index 0000000..68b1453 --- /dev/null +++ b/content/blog/virtualenv.md @@ -0,0 +1,42 @@ +--- +title: "Python Virtual Environments" +date: 2019-05-21T23:04:54-04:00 +draft: false +--- + +Dependency management is hard. Luckily with Python there is a program called `virtualenv` that can help isolate different projects and manage dependencies. + +## Commands + +To create a new python 3.7 environment type in the following: + +```bash +virtualenv --python=python3.7 environment_name +``` + +Of course you can replace the python version with whichever version you like. Now to go into the environment do the following: + +```bash +source environment_name/bin/activate +``` + +This now sets up your python interpretor and other utilities to use the installation in the `environment_name` folder. You can now install python packages using `pip` and have it only reside in this environment. + +To save all currently installed packages into `requirements.txt`: + +```bash +pip freeze > requirements.txt +``` + +You can then install those packages in a different virtualenv session with: + +```bash +pip install -r requirements.txt +``` + +You can leave the virtualenv session with: + +```bash +deactivate +``` + diff --git a/content/blog/virtualizingwithclonezilla.md b/content/blog/virtualizingwithclonezilla.md new file mode 100644 index 0000000..f7b0ba3 --- /dev/null +++ b/content/blog/virtualizingwithclonezilla.md @@ -0,0 +1,11 @@ +--- +title: "Virtualizing Environments with Clonezilla" +date: 2019-08-25T20:09:28-04:00 +draft: false +--- + +[Clonezilla](https://clonezilla.org/) advertises itself as a disk cloning and backup utility. I've been starting to think of it as a little more than that. Let's say that you go to a client site and they have a machine in production. Instead of messing around with their machine, you make a Clonezilla copy of it. You can then take it back and place it on a computer you're not using to play around with it. + +Now even better, instead of using bare metal, what if you virtualize it? It's essentially the same process as putting it on baremetal, except now you have a virtual copy that you can make clones of, backup, etc. + +Now if the OS is looking for hardware that doesn't exist, that might make life a bit harder.... \ No newline at end of file diff --git a/content/blog/virtuallivecd.md b/content/blog/virtuallivecd.md new file mode 100644 index 0000000..1f684e1 --- /dev/null +++ b/content/blog/virtuallivecd.md @@ -0,0 +1,45 @@ +--- +title: "Playing with Live CDs" +date: 2020-01-12T22:45:06-05:00 +draft: false +images: [] +--- + +I was curious on how Lubuntu 19.10 looked but I didn't feel like rebooting my computer and loading into a new ISO. Luckily there is a nice easy way to play around with live CDs. + +Here's the command + +```bash +virt-install --name=Lubuntu \ + --nodisks --livecd \ + --graphics spice \ + --vcpu=4 \ + --ram=4096 \ + --os-type=linux \ + --sound \ + --accelerate \ + --cdrom=$HOME/Downloads/lubuntu-19.10-desktop-amd64.iso +``` + +The arguments mean the following + +| Argument | Meaning | +| ---------- | ------------------------------------------------------------ | +| nodisks | No storage disks are created | +| livecd | Set the boot to the cdrom after installation | +| graphics | Sets the graphics mode | +| vcpu | Number of virtual CPUs | +| RAM | Size of RAM | +| os-type | Linux/Windows/etc. | +| sound | Attach a virtual audio device | +| accelerate | Make use of the KVM or KQEMU kernel acceleration capabilities if available. | +| cdrom | Location of ISO | + +Once you run this command once, the image is "installed". This means that we can easily access it in the future with the following commands + +```bash +virsh start Lubuntu +virt-viewer Lubuntu +``` + +![1578887790276](/files/images/1578887790276.png) \ No newline at end of file diff --git a/content/blog/vncsetup.md b/content/blog/vncsetup.md new file mode 100644 index 0000000..d488d43 --- /dev/null +++ b/content/blog/vncsetup.md @@ -0,0 +1,23 @@ +--- +title: "VNC Setup" +date: 2019-05-24T23:21:43-04:00 +draft: false +--- + +I mostly following this [Digital Ocean Tutorial](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-18-04) on getting a working VNC setup on my desktop computer. There is one main difference on my end since I use KDE. I edited the `/home/$USER/.vnc/xstartup` file to appear as + +```bash +#!/bin/sh +unset SESSION_MANAGER +unset DBUS_SESSION_BUS_ADDRESS +dbus-launch --exit-with-session startkde +``` + +And I added the following script to make my life easier + +```bash +#!/bin/bash +ssh -L 5901:127.0.0.1:5901 -C -N -l rozek 192.168.0.104 & +krdc vnc://127.0.0.1:5901 +``` + diff --git a/content/blog/whyzeromq.md b/content/blog/whyzeromq.md new file mode 100644 index 0000000..2196f75 --- /dev/null +++ b/content/blog/whyzeromq.md @@ -0,0 +1,62 @@ +--- +title: "Why ZeroMQ" +date: 2019-06-16T19:26:50-04:00 +draft: false +--- + +I've been playing around with ZeroMQ recently and it's been really exciting. This blog post is going to outline why I think you should be using ZeroMQ today. + +First of all, before you compare this to other products like RabbitMQ, DDS, etc. Realize that this is a static library that you link to in your application as opposed to a broker you run. This means that you can get the benefits with this library for very little overhead. + +## Easier Sockets + +Instead of talking about how easy ZeroMQ is to use, I'm going to just show you the code to implement a server-client relationship in Python. + +**Server.py** + +```python +import zmq +import time + +port = "5556" +context = zmq.Context() +socket = context.socket(zmq.REP) +socket.bind("tcp://*:%s" % port) + +while True: + msg = socket.recv() + print(msg) + time.sleep(1) + socket.send_string("Server Message To Client") +``` + +**Client.py** + +```python +import zmq +import time + +port = "5556" +context = zmq.Context() +socket = context.socket(zmq.REQ) +socket.connect("tcp://localhost:%s" % port) + +while True: + socket.send_string("client message to server") + time.sleep(1) + msg = socket.recv() + print(msg) + +``` + +And just like that we have a way to transport messages back and forth. No need to make a special header before each message to know the appropriate size of the packets. ZeroMQ abstracts those details from you. + +## Different Transports Available + +You're not limited to only `TCP`. You can use `inproc` for thread-to-thread messaging, `ipc` for inter-process communication, and `epgm` or `pgm` for multicast messaging. Most of the time, just changing the connection string in `socket.connect` just works! + +## Common Networking Patterns Built In + +Sometimes we just want a dumb pipe between two ends (`pipe`) but most of the times we're writing applications that follow the `server-client` or `publisher-subscriber` architecture. That gets defined in `context.socket`. + +Ex: `context.socket(zmq.PAIR)` \ No newline at end of file diff --git a/content/blog/wireguardvpn.md b/content/blog/wireguardvpn.md new file mode 100644 index 0000000..af91c76 --- /dev/null +++ b/content/blog/wireguardvpn.md @@ -0,0 +1,103 @@ +--- +title: "Wireguard VPN" +date: 2019-11-20T20:09:59-05:00 +draft: false +--- + +Having some sort of VPN solution has always been a necessity for me. Whether it's back in the day where LAN games where the rage and I wanted to play it with my distant friends, or nowadays when I need to be able to access my Desktop running simulations behind my home LAN. + +This blog post is going to describe how I settled on Wireguard VPN as my preferred solution and how I use it to create a small secured network. + +Keep note that I am not talking about a VPN that masks your internet traffic. For that, look up a VPN provider such as Private Internet Access or ProtonVPN. + +## About Wireguard + +Wireguard is a point-to-point protocol. This means that you will be exchanging public and private keys between two clients and only those two clients will communicate with one another. + +In a way this makes it a lot simpler than other VPN solutions like OpenVPN where you have to set up a key server. That doesn't mean, however, that we cannot build upon this concept to create a secure network. + +Now in order to create this network, we'll need at least one publicly accessible through the Internet computer. I use a VPS instance on [DigitalOcean](https://www.digitalocean.com/) to act as my *server*. + +## Key Generation + +First you'll want to get [Wireguard installed](https://www.wireguard.com/install/), and then create public-private keys for both the *server* and the *client* computers. + +**On each machine:** + +```bash +cd /etc/wireguard +sudo umask 077 +sudo wg genkey | tee privatekey | wg pubkey > publickey +``` + +**On the server:** + +Edit `/etc/wireguard/wg0.conf` + +```yaml +[Interface] +Address = 10.10.100.1/24 +SaveConfig = false +ListenPort = 51826 +PrivateKey = + +[Peer] +PublicKey = +AllowedIPs = 10.10.100.2/32 + +[Peer] +PublicKey = +AllowedIPs = 10.10.100.3/32 +``` + +You might be wondering why we have `/24` in the Address field but `/32` in the AllowedIPs field. + +This is because we want our address to be in the `/24` subnet, but we only want that specific IP to be able to connect via that specific public key. + +Warning: Make sure you have 51826 open on your firewall. + +Now to have your server route traffic between the different clients connected to it, you need to enable IPv4 forwarding. + +*For current session:* + +```bash +sysctl -w net.ipv4.ip_forward=1 +``` + +*For persistence across reboots:* + +Edit `/etc/sysctl.d/99-sysctl.conf` to make sure `net.ipv4.ip_forward=1` + +**On the client machines:** + +Edit `/etc/wireguard/wg0.conf` + +```yaml +[Interface] +Address = 10.10.100.x/32 +PrivateKey = +PostUp = ping -c1 10.10.100.1 +DNS = 10.10.100.y # Include only if relevant + +[Peer] +PublicKey = +Endpoint = public_ip_or_domain:51826 +AllowedIPs = 10.10.100.0/24 +PersistentKeepalive = 21 +``` + +Replace `x` with a unique value per client. This configuration file has the client establish a connection to the server, send a packet via ping to initiate the connection and then try to persistently keep it alive. + +The DNS server is helpful if you have a DNS server running in that private network to access local resources. If you don't have an existing DNS server in the network, do not include that line. Also if you receive any errors in the future, you might need to make sure `resolvconf` is a command on your system. + +**On all machines:** + +Have the wireguard service start at boot + +```bash +sudo systemctl enable wg-quick@wg0 +sudo systemctl start wg-quick@wg0 +``` + +And enjoy a fully secure routable network! + diff --git a/content/blog/wormhole.md b/content/blog/wormhole.md new file mode 100644 index 0000000..bed32ca --- /dev/null +++ b/content/blog/wormhole.md @@ -0,0 +1,23 @@ +--- +title: "Wormhole" +date: 2019-11-20T21:21:23-05:00 +draft: false +--- + +A dead simple way to send files between two linux machines not on the same network is to use a utility called [Magic Wormhole](https://github.com/warner/magic-wormhole). It is typically included in the standard repositories and is so simple the this blog post is going to end soon. + +**Send a file:** + +```bash +wormhole send filename +``` + +This will generate a code for you to share like `6-speculate-allow` + +**Receive a file:** + +```bash +wormhole receive 6-speculate-allow +``` + +Done. diff --git a/content/blog/xephyr.md b/content/blog/xephyr.md new file mode 100644 index 0000000..f32fe08 --- /dev/null +++ b/content/blog/xephyr.md @@ -0,0 +1,55 @@ +--- +title: "Nested X Sessions with Xephyr" +date: 2019-12-25T00:52:02-05:00 +draft: false +images: [] +--- + +The X Window System was designed at a time when applications that ran on your computer were assumed to be trusted. Therefore there are minimal restrictions in place to prevent applications from grabbing images of whats on another applications screens. This feature as you might imagine is quite useful for screen clipper applications. + +Now I know that we're slowly moving towards Wayland on the Linux desktop, but X11 is still a reality even in my KDE Neon version that's based on Ubuntu 18.04. + +So in the meantime, we can put our untrusted applications into a nested X server using `Xephyr`. + +First, we need to find an empty display variable. Chances are this would be `:1` for you. Though if you have multiple of these nested X-sessions running, then this script will be handy. + +```bash +for ((DNum=1 ; DNum <= 100 ; DNum++)) ; do + [ -e /tmp/.X11-unix/X$DNum ] || break +done +``` + +At the end, `DNum` will be set to an empty display variable. + +Then to start your nested X session, + +```bash +Xephyr :$DNum \ + -extension MIT-SHM \ + -extension XTEST \ + -nolisten tcp \ + -screen 1920x1080 \ + -resizeable & +``` + +If we're going to be using this nested X server for one application, then I recommend using the `ratpoison` window manager as it will make the application full screen and supports the reizability of the Xephyr window. + +```bash +ratpoison -d :$DNum & +``` + +Finally, you should set your display variable so that any future GUI applications you execute from the terminal will show up in your new Xephyr window. + +```bash +DISPLAY=:$DNum +``` + +Now if you want to run multiple applications, you're likely better off using your native window manager. + +```bash +# Set the display before starting the window manager +DISPLAY=:$DNum +x-window-manager & +``` + +Of course you can replace ratpoison and your native x-window manager with any other window manager of your choice. It actually makes it a great way to test different environments. \ No newline at end of file diff --git a/content/blog/xpra.md b/content/blog/xpra.md new file mode 100644 index 0000000..829db2c --- /dev/null +++ b/content/blog/xpra.md @@ -0,0 +1,58 @@ +--- +title: "xpra" +date: 2020-01-15T18:29:57-05:00 +draft: false +images: [] +--- + +[`xpra`](http://xpra.org/) allows one to run persistent X applications on a remote host and display it on a local machine. It's a combination of [SSH X11 Forwarding](https://wiki.archlinux.org/index.php/OpenSSH#X11_forwarding) and [Screen](https://www.gnu.org/software/screen/). + +To get started you need to install the `xpra` package on both the server and client. On Ubuntu 18.04, this package isn't configured properly so one should use this PPA instead. + +```bash +sudo add-apt-repository ppa:mikhailnov/xpra +``` + +To install, + +```bash +sudo apt install xpra +``` + +Now you can from the client open up an application with one command + +```bash +xpra start ssh:user@host --exit-with-children --start-child="executable" +``` + +If you want it to behave more like screen. Then on the server. + +```bash +xpra start :100 +``` + +Where you can replace `:100` with another high display number. + +Then you can run the executable, + +```bash +DISPLAY=:100 executable +``` + +From the client, + +```bash +xpra attach ssh:user@host:100 +``` + +`xpra` has heuristics that determines the encoding of the images passed. You can however override it using the `--encoding`s flag to better tailor to your needs. + +- `rgb`: Raw pixel format that is lossless and uses compression. Best in high bandwidth environments. +- `png` compressed, lossless, but CPU intensive. May result in skipped frames +- `h264`, `vp8`, `vp9` are lossy formats that have tunable quality and speed parameters + + +More resources: +- [Arch Wiki](https://wiki.archlinux.org/index.php/Xpra) +- [Ubuntu Wiki](https://help.ubuntu.com/community/Xpra) + diff --git a/content/blog/yubikey.md b/content/blog/yubikey.md new file mode 100644 index 0000000..8cd53f1 --- /dev/null +++ b/content/blog/yubikey.md @@ -0,0 +1,14 @@ +--- +title: "YubiKey" +date: 2019-07-07T14:31:47-04:00 +draft: false +--- + +The YubiKey is a hardware authentication device manufactured by Yubico. It is a write only device that is meant to hold various authentication keys. The fact that it is write only means that people can't duplicate these keys. [Noah Chelliah](https://twitter.com/kernellinux) from Altispeed says that he uses YubiKeys at his company so that when employees moves on from his company he only needs to take their YubiKey. + +Now I don't manage any infrastructure larger than a couple computers, so why are these things interesting from a home use perspective? Well it allows you to have two-factor authentication separate from your smart phone. I was never a large fan of using my cell phone for two factor since you usually change cell phones every couple years. + +What I wanted to highlight is how easy it is to integrate it with Linux. The Pluggable Authentication Module (PAM) is responsible for authentication and other various utilities in Linux. By adding a couple of lines to a couple of text files, you can add two-factor authentication to your laptop! + +Instead of rewriting a bunch of instructions I got from somewhere else, I'll direct you to Yubico's own [documentation entry](https://developers.yubico.com/yubico-pam/Authentication_Using_Challenge-Response.html). Happy hacking! + diff --git a/content/community.md b/content/community.md new file mode 100644 index 0000000..c854e93 --- /dev/null +++ b/content/community.md @@ -0,0 +1,22 @@ +--- +title: Community +description: Various groups and activities that I participate in +--- + +## ./UMWLUG +I was the co-founder and vice president of UMW's Linux Users Group. I mainly brought interesting people to come and talk about Linux and open source. + +[Main Website](https://umwlug.github.io/) + +[My Records](umwlug) + +## Cybersecurity - Capture the Flag +Capture the Flag (CTF) is a competition in where teams try to find *flags* by doing different types of cybersecurity type problems. This can include using the wayback machine, breaking a simple cryptosystem, as well as finding exploits in a sandboxed system. + +I was part of a committee of four people making problems for UMW's first CTF competition. + +If you're interested in this sort of thing and just starting out, one website that I found which is really cool is called [OverTheWire](https://overthewire.org/wargames/bandit/). + +## Datakind + +In the summer of 2018, I attended the month Datakind events in DC. In it, I mostly performed data cleaning and verification for non-profit organizations in the area. diff --git a/content/community/_index.md b/content/community/_index.md new file mode 100644 index 0000000..e69de29 diff --git a/content/community/umwlug.md b/content/community/umwlug.md new file mode 100644 index 0000000..4ac7145 --- /dev/null +++ b/content/community/umwlug.md @@ -0,0 +1,32 @@ +--- +title: ./UMWLUG +description: My involvement in UMW's Linux Users Group +--- + +## Sweet Logo Designs + +I have a small amount of pride in the logos I made for this group. Check them out! + +[Light Theme Logo](/files/umwlug/logo.pdf) + +[Dark Theme Logo](/files/umwlug/darklogo.pdf) + +## Events Organized +I helped organize a variety of different events while I was part of the group, below are the link to the fliers I designed for them: + +[Cybersecurity: The Art of Analyzing, Protecting, and Defending your Network](/files/umwlug/tedtalk.pdf) + +[Fall 2019 Interest Meeting](/files/umwlug/interestfall2019.pdf) + +[How I Get Paid to Write Free Software](/files/umwlug/petertalk.pdf) + +[Spring 2019 Interest Meeting](/files/umwlug/interestspring2019.pdf) + +[Linux Audio Workshop](/files/umwlug/audio.pdf) + +[Fall 2018 Interest Meeting](/files/umwlug/interestfall2018.pdf) + +[Linux/Unix: Why are they related, but not the same](/files/umwlug/linuxvunix.pdf) + +[Spring 2018 Interest Meeting](/files/umwlug/interestspring2018.pdf) + diff --git a/content/notes.md b/content/notes.md new file mode 100644 index 0000000..281baaf --- /dev/null +++ b/content/notes.md @@ -0,0 +1,26 @@ +--- +title: Notes +description: Documents pertaining to courses I've taken +--- + +# Courses + +Below are the courses that I have documents up online for. + +[Probability and Statistical Inference I](stat381) + +[Real Analysis Quick Facts](realanalysis) + +[Some Abstract 2 Definitions](abstract2def) + +[Handy Facts about Quadratic Congruences](quadraticcongruences) + +## Coursera Courses +Occassionally during breaks, I like to take some coursera courses. I will post my notes from the lecture here as well. + +[Bayesian Statistics](bayesianstatistics) + +[Reproducible Research](reproducibleresearch) + +## Self/Small Group Study +Chris Richters, Ethan Martin, and I embarked on the book ["Algorithms" by Jeff Erickson](http://jeffe.cs.illinois.edu/teaching/algorithms/). I took some notes during our discussions but you should really just read the book instead. [Notes Page](algorithms) diff --git a/content/notes/.Stat381.md.swp b/content/notes/.Stat381.md.swp new file mode 100644 index 0000000..fb7c6e9 Binary files /dev/null and b/content/notes/.Stat381.md.swp differ diff --git a/content/notes/_index.md b/content/notes/_index.md new file mode 100644 index 0000000..e69de29 diff --git a/content/notes/abstract2def.md b/content/notes/abstract2def.md new file mode 100644 index 0000000..d3a8009 --- /dev/null +++ b/content/notes/abstract2def.md @@ -0,0 +1,73 @@ +# Abstract Algebra 2 Definitions + +## Chapter 17 + +By a **ring** we mean a set $A$ with operations called addition and multiplication which satisfy the following axioms: + +- $A$ with addition alone is an abelian group +- Multiplication is associative +- Multiplication is distributive over addition + +Since $\langle A, + \rangle$ is an abelian group, there is in $A$ a neutral element for addition. This is called the **zero** element. Also, every element has an additive inverse called its **negative**. + +If multiplication in a ring $A$ is commutative then we say that $A$ is a **commutative ring**. + +If a ring $A$ has a neutral element for multiplication then we say that the neutral element is the **unity** of $A$. + +If $A$ is a ring with unity, there may be elements in $A$ which have a multiplicative inverse. Such elements are said to be **invertible**. + +If $A$ is a commutative ring with unity in which every nonzero element is invertible, then $A$ is called a **field**. + +In any ring, a nonzero element $a$ is called a **divisor of zero** if there is a nonzero element $b$ in a ring such that the product $ab$ or $ba$ is equal to zero. + +An **integral domain** is defined to be a commutative ring with unity that has the cancellation property. Another way of saying this is that an integral domain is a commutative ring with unity and has no zero divisors. + +## Chapter 18 + +Let $A$ be a ring, and $B$ be a nonempty subset of $A$. $B$ is called a **subring** if it satisfies the following properties: + +- Closed with respect to addition +- Closed with respect to negatives +- Closed with respect to multiplication + +Let $B$ be a subring of $A$. We call $B$ an **ideal** of $A$ if $xb, bx \in B$ for all $b \in B$ and $x \in A$. + +The **principle ideal generated by $a$**, denoted $\langle a \rangle$ is the subring defined by fixing an element $a$ in a subring $B$ of $A$ and multiplying all elements of $A$ by $a$. +$$ +\langle a \rangle = \{ xa : x \in A \} +$$ +A **homomorphism** from a ring $A$ to a ring $B$ is a function $f : A \to B$ satisfying the identities: +$$ +f(x_1 + x_2 ) = f(x_1) + f(x_2) \\ +f(x_1x_2) = f(x_1)f(x_2) +$$ +If there is a homomorphism from $A$ onto $B$, we call $B$ a **homomorphic image** of $A$. + +If $f$ is a homomorphism from a ring $A$ to a ring $B$, the **kernel** of $f$ is the set of all the elements of $A$ which are carried by $f$ onto the zero element of $B$. In symbols, the kernel of $f$ is the set +$$ +K = \{x \in A: f(x) = 0\} +$$ +If $A$ and $b$ are rings, an **isomorphism** from $A$ to $B$ is a homomorphism which is a one-to-one correspondence from $A$ to $B$. In other words, it is injective and surjective homomorphism. + +If there is an isomorphism from $A$ to $B$ we say that $A$ is **isomorphic** to $B$, and this fact is expressed by writing $A \cong B$. + +## Chapter 19 + +Let $A$ be a ring, and $J$ an ideal of $A$. For any element $a \in A$, the symbol $J + a$ denotes the set of all sums $j + a$ as $a$ remains fixed and $j$ ranges over $J$. That is, +$$ +J + a = \{j + a : j \in J\} +$$ +$J + a$ is called a **coset** of $J$ in $A$. + +Now think of the set which contains all cosets of $J$ in $A$. This set is conventionally denoted by $A / J$ and reads $A$ mod $J$. Then, $A / J$ with coset addition and multiplication is a ring. + +An ideal $J$ of a commutative ring is said to be a **prime ideal** if for any two elements $a$ and $b$ in the ring, +$$ +ab \in J \implies a \in J \text{ or } b \in J +$$ +Theorem: If $J$ is a prime ideal of a community ring with unity $A$, then the quotient ring $A / J$ is an integral domain. + +An ideal $J$ of $A$ with $J \ne A$ is called a **maximal ideal** if there exists no proper ideal $K$ of $A$ such that $J \subseteq K$ with $J \ne K$. + +Theorem: If $A$ is a commutative ring with unity, then $J$ is a maximal ideal of $A$ iff $A/J$ is a field. + diff --git a/content/notes/algorithms.md b/content/notes/algorithms.md new file mode 100644 index 0000000..9178b7b --- /dev/null +++ b/content/notes/algorithms.md @@ -0,0 +1,17 @@ +--- +title: Algorithms Book Study +--- + +# Algorithms Book Study +A couple of my friends and I decided to start a book club following "Algorithms" by Jeff Erickson. One bonus is that he gives it away for free on [his website](http://jeffe.cs.illinois.edu/teaching/algorithms/)! + +Of course you should totally check his book out rather than reading my notes. There are tons of witty and fun things in his textbook, not a dry reading I promise. These notes are here mostly for archival purposes. + +## Notes +[Chapter 1](recursion) + +[Chapter 2](backtracking) + +[Chapter 3](dynamic) + +[Chapter 4](greedy) \ No newline at end of file diff --git a/content/notes/algorithms/backtracking.md b/content/notes/algorithms/backtracking.md new file mode 100644 index 0000000..5f9c7ae --- /dev/null +++ b/content/notes/algorithms/backtracking.md @@ -0,0 +1,62 @@ +# Backtracking +This algorithm tries to construct a solution to a problem one piece at a time. Whenever the algorithm needs to decide between multiple alternatives to the part of the solution it *recursively* evaluates every option and chooses the best one. + + +## How to Win +To beat any *non-random perfect information* game you can define a Backtracking algorithm that only needs to know the following. +- A game state is good if either the current player has already won or if the current player can move to a bad state for the opposing player. +- A game state is bad if either the current player has already lost or if every available move leads to a good state for the opposing player. + +``` +PlayAnyGame(X, player) + if player has already won in state X + return GOOD + if player has lost in state X + return BAD + for all legal moves X -> Y + if PlayAnyGame(y, other player) = Bad + return GOOD + return BAD +``` + +In practice, most problems have an enormous number of states not making it possible to traverse the entire game tree. + +## Subset Sum + +For a given set, can you find a subset that sums to a certain value? + +``` +SubsetSum(X, T): + if T = 0 + return True + else if T < 0 or X is empty + return False + else + x = any element of X + with = SubsetSum(X \ {x}, T - x) + without = SubsetSum(X \ {x}, T) + return (with or without) +``` + +X \ {x} denotes set subtraction. It means X without x. + +``` +ConstructSubset(X, i, T): + if T = 0 + return empty set + if T < 0 or n = 0 + return None + Y = ConstructSubset(X, i - 1, T) + if Y does not equal None + return Y + Y = ConstructSubset(X, i - 1, T - X[i]) + if Y does not equal None + return Y with X[i] + return None +``` + +## Big Idea + +Backtracking algorithms are used to make a *sequence of decisions*. + +When we design a new recursive backtracking algorithm, we must figure out in advance what information we will need about past decisions in the middle of the algorithm. \ No newline at end of file diff --git a/content/notes/algorithms/dynamic.md b/content/notes/algorithms/dynamic.md new file mode 100644 index 0000000..5d1b785 --- /dev/null +++ b/content/notes/algorithms/dynamic.md @@ -0,0 +1,82 @@ +# Dynamic Programming + +The book first goes into talking about the complexity of the Fibonacci algorithm + +``` +RecFibo(n): + if n = 0 + return 0 + else if n = 1 + return 1 + else + return RecFibo(n - 1) + RecFibo(n - 2) +``` + +It talks about how the complexity of this is exponential. + +"A single call to `RecFibo(n)` results in one recursive call to `RecFibo(n−1)`, two recursive calls to `RecFibo(n−2)`, three recursive calls to `RecFibo(n−3)`, five recursive calls to `RecFibo(n−4)`" + +Now consider the memoized version of this algorithm... + +``` +MemFibo(n): + if n = 0 + return 0 + else if n = 1 + return 1 + else + if F[n] is undefined: + F[n] <- MemFibo(n - 1) + MemFibo(n - 2) + return F[n] +``` + +This actually makes the algorithm run in linear time! + +![1564017052666](/home/rozek/Documents/StudyGroup/Algorithms/1564017052666.png) + +Dynamic programming makes use of this fact and just intentionally fills up an array with the values of $F$. + +``` +IterFibo(n): + F[0] <- 0 + F[1] <- 1 + for i <- 2 to n + F[i] <- F[i - 1] + F[i - 2] + return F[n] +``` + +Here the linear complexity becomes super apparent! + +Interesting snippet + +"We had a very interesting gentleman in Washington named Wilson. He was secretary of Defense, and he actually had a pathological fear and hatred of the word *research*. I’m not using the term lightly; I’m using it precisely. His face would suffuse, he would turn red, and he would get violent if people used the term *research* in his presence. You can imagine how he felt, then, about the term *mathematical*.... I felt I had to do something to shield Wilson and the Air Force from the fact that I was really doing mathematics inside the RAND Corporation. What title, what name, could I choose?" + + + +Dynamic programming is essentially smarter recursion. It's about not repeating the same work. + +These algorithms are best developed in two distinct stages. + +(1) Formulate the problem recursively. + +(a) Specification: What problem are you trying to solve? + +(b) Solution: Why is the whole problem in terms of answers t smaller instances exactly the same problem? + +(2) Find solutions to your recurrence from the bottom up + +(a) Identify the subproblems + +(b) Choose a memoization data structure + +(c) Identify dependencies + +(d) Find a good evaluation order + +(e) Analyze space and running time + +(f) Write down the algorithm + +## Greedy Algorithms + +If we're lucky we can just make decisions directly instead of solving any recursive subproblems. The problem is that greedly algorithms almost never work. \ No newline at end of file diff --git a/content/notes/algorithms/greedy.md b/content/notes/algorithms/greedy.md new file mode 100644 index 0000000..5477c9a --- /dev/null +++ b/content/notes/algorithms/greedy.md @@ -0,0 +1,36 @@ +# Greedy Algorithms + +Greedy Algorithms are about making the best local choice and then blindly plowing ahead. + +An example of this is documents on a tape. Let's say to read any given document on a tape, you first need to read all the documents that come before it. + +What is the best way to have the documents laid out in order to decrease the expected read time? + +Answer: Putting the smaller documents first. + +The book then generalizes it further by adding access frequencies. The answer to that is to sort by increasing length first and then decreasing access times. + +## Scheduling Classes +To maximize the number of classes one can take one greedy algorithm is to always select the class that ends first. + +That will produce one maximal conflict free schedule. + +## Structure of Correctness Proofs for Greedy Algorithms + +- Assume that there is an optimal solution that is different from the greedy solution. +- Find the first "difference" between the two solutions. +- Argue that we can exchange the optimal choice for the greedy choice without making the solution worse. + +## Hospital-Doctor Matching +Let's say you have a list of doctors that need internships and hospitals accepting interns. We need to make it so that every doctor has a job and every hospital has a doctor. + +Assuming we have the same number of doctors and hospitals and that each hospital offers only one internship, how do we make an algorithm to ensure that no unstable matchings exist? + +An unstable match is when +- a is matched with some other hospital A even though she prefers B +- B is matched with some doctor b even though they prefer a. + +The Gale-Shapley algorithm is a great greedy fit. It goes like this + +1. An arbitrary unmatched hospital A offers its position to the best doctor a who has not already rejected it. +2. If a is unmatched, she tentatively accepts A's offer. If a already had a match but prefers A, she rejects her current match and tentatively accepts the new offer from A. Otherwise a rejects the new offer. \ No newline at end of file diff --git a/content/notes/algorithms/recursion.md b/content/notes/algorithms/recursion.md new file mode 100644 index 0000000..96c2383 --- /dev/null +++ b/content/notes/algorithms/recursion.md @@ -0,0 +1,86 @@ +# Recursion + +## Reductions + +Quote: *Reduction* is the single most common technique used in designing algorithms. Reduce one problem $X$ to another problem $Y$. + +The running time of the algorithm can be affected by $Y$, but $Y$ does not affect the correctness of the algorithm. So it is often useful to not be concerned with the inner workings of $Y$. + +## Simplify and Delegate + +Quote: *Recursion* is a particularly powerful kind of reduction, which can be described loosely as follows: + +- If the given instance of the problem can be solved directly, then do so. +- Otherwise, reduce it to one or more **simpler instances of the same problem.** + +The book likes to call the delegation of simpler tasks "giving it to the recursion fairy." + +Your own task as an algorithm writer is to simplify the original problem and solve base cases. The recursion fairy will handle the rest. + +Tying this to mathematics, this is known as the **Induction Hypothesis**. + +The only caveat is that simplifying the tasks must eventually lead to the **base case** otherwise the algorithm might run infinitely! + +#### Example: Tower of Hanoi + +Assuming you know how the game works, we will describe how to solve it. + +Quote: We can't move it all at the beginning, because all the other disks are in the way. So first we have to move those $n - 1$ smaller disks to the spare peg. Once that's done we can move the largest disk directly to its destination. Finally to finish the puzzle, we have to move the $n -1$ disks from the spare peg to the destination. + +**That's it.** + +Since the problem was reduced to a base case and a $(n - 1)$ problem, we're good. The book has a funny quote "Our job is finished. If we didn't trust the junior monks, we wouldn't have hired them; let them do their job in peace." + + ``` +Hanoi(n, src, dst, tmp): + if n > 0 + Hanoi(n - 1, src, tmp, dst) + move disk n from src to dst + Hanoi(n - 1, tmp, dst, src) + ``` + +## Sorting Algorithms + +## Merge Sort + +``` +MergeSort(A[1..n]): + if n > 1 + m = floor(n / 2) + MergeSort(A[1..m]) + MergeSort(A[m + 1..n]) + Merge(A[1..n], m) +``` + +``` +Merge(A[1..n], m): + i = 1 + j = m + 1 + for k = 1 to n + if j > n + B[k] = A[i] + i++ + else if i > m + B[k] = A[j] + j++ + else if A[i] < A[j] + B[k] = A[i] + i++ + else + B[k] = A[j] + j++ + Copy B to A +``` + +I think an important part to recall here is that the algorithm will break it down to the lowest level. An array with one element and slowly work its way up. + +That means we can always assume that each subarray that we're merging is already sorted! Which is why the merge algorithm is written the way it is. + +## The Pattern + +This section is quoted verbatim. + +1. **Divide** the given instance of the problem into several *independent smaller* instances of *exactly* the same problem. +2. **Delegate** each smaller instance to the Recursion Fairy. +3. **Combine** the solutions for the smaller instances into the final solution for the given instance. + diff --git a/content/notes/bayesianstatistics.md b/content/notes/bayesianstatistics.md new file mode 100644 index 0000000..84a1897 --- /dev/null +++ b/content/notes/bayesianstatistics.md @@ -0,0 +1,20 @@ +--- +title: Bayesian Statistics +showthedate: false +--- + + + +# Bayesian Statistics: From Concept to Data Analysis + +In the Winter of 2017, I took a course on Bayesian Statistics on Coursera offered by Dr. Herbert Lee. + +Below are the notes for each of the four weeks. + +[Week 1](week1) + +[Week 2](week2) + +[Week 3](week3) + +[Week 4](week4) diff --git a/content/notes/bayesianstatistics/week1.md b/content/notes/bayesianstatistics/week1.md new file mode 100644 index 0000000..3480a84 --- /dev/null +++ b/content/notes/bayesianstatistics/week1.md @@ -0,0 +1,413 @@ +# Bayesian Statistics + +## Rules of Probability + +Probabilities must be between zero and one, i.e., $0≤P(A)≤1$ for any event A. + +Probabilities add to one, i.e., $\sum{P(X_i)} = 1$ + +The complement of an event, $A^c$, denotes that the event did not happen. Since probabilities must add to one, $P(A^c) = 1 - P(A)$ + +If A and B are two events, the probability that A or B happens (this is an inclusive or) is the probability of the union of the events: +$$ +P(A \cup B) = P(A) + P(B) - P(A\cap B) +$$ +where $\cup$ represents union ("or") and $\cap$ represents intersection ("and"). If a set of events $A_i$ are mutually exclusive (only one event may happen), then +$$ +P(\cup_{i=1}^n{A_i}) = \sum_{i=1}^n{P(A_i)} +$$ + +## Odds + +The odds for event A, denoted $\mathcal{O}(A)$ is defined as $\mathcal{O}(A) = P(A)/P(A^c)$ + +This is the probability for divided by probability against the event + +From odds, we can also compute back probabilities +$$ +\frac{P(A)}{P(A^c)} = \mathcal{O}(A) +$$ + +$$ +\frac{P(A)}{1-P(A)} = \mathcal{O}(A) +$$ + +$$ +\frac{1 -P(A)}{P(A)} = \frac{1}{\mathcal{O}(A)} +$$ + +$$ +\frac{1}{P(A)} - 1 = \frac{1}{\mathcal{O}(A)} +$$ + +$$ +\frac{1}{P(A)} = \frac{1}{\mathcal{O}(A)} + 1 +$$ + +$$ +\frac{1}{P(A)} = \frac{1 + \mathcal{O}(A)}{\mathcal{O}(A)} +$$ + +$$ +P(A) = \frac{\mathcal{O}(A)}{1 + \mathcal{O}(A)} +$$ + +## Expectation + +The expected value of a random variable X is a weighted average of values X can take, with weights given by the probabilities of those values. +$$ +E(X) = \sum_{i=1}^n{x_i * P(X=x_i)} +$$ + +## Frameworks of probability + +Classical -- Outcomes that are equally likely have equal probabilities + +Frequentist -- In an infinite sequence of events, what is the relative frequency + +Bayesian -- Personal perspective (your own measure of uncertainty) + +In betting, one must make sure that all the rules of probability are followed. That the events are "coherent", otherwise one might construct a series of bets where you're guaranteed to lose money. This is referred to as a Dutch book. + +## Conditional probability + +$$ +P(A|B) = \frac{P(A\cup B)}{P(B)} +$$ + +Where $A|B$ denotes "A given B" + +Example from lecture: + +Suppose there are 30 students, 9 of which are female. From the 30 students, 12 are computer science majors. 4 of those 12 computer science majors are female +$$ +P(Female) = \frac{9}{30} = \frac{3}{10} +$$ + +$$ +P(CS) = \frac{12}{30} = \frac{2}{5} +$$ + +$$ +P(F\cap CS) = \frac{4}{30} = \frac{2}{15} +$$ + +$$ +P(F|CS) = \frac{P(F \cap CS)}{P(CS)} = \frac{2/15}{2/5} = \frac{1}{3} +$$ + +An intuitive way to think about a conditional probability is that we're looking at a subsegment of the original population, and asking a probability question within that segment +$$ +P(F|CS^c) = \frac{P(F\cap CS^c)}{PS(CS^c)} = \frac{5/30}{18/30} = \frac{5}{18} +$$ +The concept of independence is when one event does not depend on another. +$$ +P(A|B) = P(A) +$$ +It doesn't matter that B occurred. + +If two events are independent then the following is true +$$ +P(A\cap B) = P(A)P(B) +$$ +This can be derived from the conditional probability equation. + +## Conditional Probabilities in terms of other conditional + +Suppose we don't know what $P(A|B)$ is but we do know what $P(B|A)$ is. We can then rewrite $P(A|B)$ in terms of $P(B|A)$ +$$ +P(A|B) = \frac{P(B|A)P(A)}{P(B|A)P(A) + P(B|A^c)P(A^c)} +$$ +Let's look at an example of an early test for HIV antibodies known as the ELISA test. +$$ +P(+ | HIV) = 0.977 +$$ + +$$ +P(- | NO\_HIV) = 0.926 +$$ + +As you can see over 90% of the time, this test was accurate. + +The probability of someone in North America having this disease was $P(HIV) = .0026$ + +Now let's consider the following problem: the probability of having the disease given that they tested positive $P(HIV | +)$ +$$ +P(HIV|+) = \frac{P(+|HIV)P(HIV)}{P(+|HIV)P(HIV) + P(+|NO\_HIV){P(NO\_HIV)}} +$$ + +$$ +P(HIV|+) = \frac{(.977)(.0026)}{(.977)(.0026) + (1-.977)(1-.0026)} +$$ + +$$ +P(HIV|+) = 0.033 +$$ + +This example looked at Bayes Theorem for the two event case. We can generalize it to n events through the following formula +$$ +P(A|B) = \frac{P(B|A_1){(A_1)}}{\sum_{i=1}^{n}{P(B|A_i)}P(A_i)} +$$ + + + +## Bernoulli Distribution + +~ means 'is distributed as' + +We'll be first studying the Bernoulli Distribution. This is when your event has two outcomes, which is commonly referred to as a success outcome and a failure outcome. The probability of success is $p$ which means the probability of failure is $(1-p)$ +$$ +X \sim B(p) +$$ + +$$ +P(X = 1) = p +$$ + +$$ +P(X = 0) = 1-p +$$ + +The probability of a random variable $X$ taking some value $x$ given $p$ is +$$ +f(X = x | p) = f(x|p) = p^x(1-p)^{1 - x}I +$$ +Where $I$ is the Heavenside function + +Recall the expected value +$$ +E(X) = \sum_{x_i}{x_iP(X=x_i)} = (1)p + (0)(1-p) = p +$$ +We can also define the variance of Bernoulli +$$ +Var(X) = p(1-p) +$$ + +## Binomial Distribution + +The binomial distribution is the sum of n *independent* Bernoulli trials +$$ +X \sim Bin(n, p) +$$ + +$$ +P(X=x|p) = f(x|p) = {n \choose x} p^x (1-p)^{n-x} +$$ + +$n\choose x$ is the combinatoric term which is defined as +$$ +{n \choose x} = \frac{n!}{x! (n - x)!} +$$ + +$$ +E(X) = np +$$ + +$$ +Var(X) = np(1-p) +$$ + +## Uniform distribution + +Let's say X is uniformally distributed +$$ +X \sim U[0,1] +$$ + +$$ +f(x) = \left\{ + \begin{array}{lr} + 1 & : x \in [0,1]\\ + 0 & : otherwise + \end{array} + \right. +$$ + +$$ +P(0 < x < \frac{1}{2}) = \int_0^\frac{1}{2}{f(x)dx} = \int_0^\frac{1}{2}{dx} = \frac{1}{2} +$$ + +$$ +P(0 \leq x \leq \frac{1}{2}) = \int_0^\frac{1}{2}{f(x)dx} = \int_0^\frac{1}{2}{dx} = \frac{1}{2} +$$ + +$$ +P(x = \frac{1}{2}) = 0 +$$ + +## Rules of probability density functions + +$$ +\int_{-\infty}^\infty{f(x)dx} = 1 +$$ + +$$ +f(x) \ge 0 +$$ + +$$ +E(X) = \int_{-\infty}^\infty{xf(x)dx} +$$ + +$$ +E(g(X)) = \int{g(x)f(x)dx} +$$ + +$$ +E(aX) = aE(X) +$$ + +$$ +E(X + Y) = E(X) + E(Y) +$$ + +If X & Y are independent +$$ +E(XY) = E(X)E(Y) +$$ + +## Exponential Distribution + +$$ +X \sim Exp(\lambda) +$$ + +Where $\lambda$ is the average unit between observations +$$ +f(x|\lambda) = \lambda e^{-\lambda x} +$$ + +$$ +E(X) = \frac{1}{\lambda} +$$ + +$$ +Var(X) = \frac{1}{\lambda^2} +$$ + +## Uniform (Continuous) Distribution + +$$ +X \sim [\theta_1, \theta_2] +$$ + +$$ +f(x|\theta_1,\theta_2) = \frac{1}{\theta_2 - \theta_1}I_{\theta_1 \le x \le \theta_2} +$$ + +## Normal Distribution + +$$ +X \sim N(\mu, \sigma^2) +$$ + +$$ +f(x|\mu,\sigma^2) = \frac{1}{\sqrt{2\pi \sigma^2}}e^{-\frac{1}{2\sigma^2}(x-\mu)^2} +$$ + +$$ +E(X) = \mu +$$ + +$$ +Var(X) = \sigma^2 +$$ + +## Variance + +Variance is the squared distance from the mean +$$ +Var(X) = \int_{-\infty}^\infty {(x - \mu)^2f(x)dx} +$$ + +## Geometric Distribution (Discrete) + +The geometric distribution is the number of trails needed to get the first success, i.e, the number of Bernoulli events until a success is observed. +$$ +X \sim Geo(p) +$$ + +$$ +P(X = x|p) = p(1-p)^{x-1} +$$ + +$$ +E(X) = \frac{1}{p} +$$ + +## Multinomial Distribution (Discrete) + +Multinomial is like a binomial when there are more than two possible outcomes. + + +$$ +f(x_1,...,x_k|p_1,...,p_k) = \frac{n!}{x_1! ... x_k!}p_1^{x_1}...p_k^{x_k} +$$ + +## Poisson Distribution (Discrete) + +The Poisson distribution is used for counts. The parameter $\lambda > 0$ is the rate at which we expect to observe the thing we are counting. +$$ +X \sim Pois(\lambda) +$$ + +$$ +P(X=x|\lambda) = \frac{\lambda^xe^{-\lambda}}{x!} +$$ + +$$ +E(X) = \lambda +$$ + +$$ +Var(X) = \lambda +$$ + +## Gamma Distribution (Continuous) + +If $X_1, X_2, ..., X_n$ are independent and identically distributed Exponentials,waiting time between success events, then the total waiting time for all $n$ events to occur will follow a gamma distribution with shape parameter $\alpha = n$ and rate parameter $\beta = \lambda$ +$$ +Y \sim Gamma(\alpha, \beta) +$$ + +$$ +f(y|\alpha,\beta) = \frac{\beta^n}{\Gamma(\alpha)}y^{n-1}e^{-\beta y}I_{y\ge0}(y) +$$ + +$$ +E(Y) = \frac{\alpha}{\beta} +$$ + +$$ +Var(Y) = \frac{\alpha}{\beta^2} +$$ + +Where $\Gamma(x)$ is the gamma function. The exponential distribution is a special case of the gamma distribution with $\alpha = 1$. As $\alpha$ increases, the gamma distribution more closely resembles the normal distribution. + +## Beta Distribution (Continuous) + +The beta distribution is used for random variables which take on values between 0 and 1. For this reason, the beta distribution is commonly used to model probabilities. +$$ +X \sim Beta(\alpha, \beta) +$$ + +$$ +f(x|\alpha,\beta) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}x^{n -1}(1 - x)^{\beta - 1}I_{\{0 < x < 1\}} +$$ + +$$ +E(X) = \frac{\alpha}{\alpha + \beta} +$$ + +$$ +Var(X) = \frac{\alpha\beta}{(\alpha + \beta)^2(\alpha+\beta+1)} +$$ + +The standard uniform distribution is a special case of the beta distribution with $\alpha = \beta = 1$ + +## Bayes Theorem for continuous distribution + +$$ +f(\theta|y) = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} +$$ + diff --git a/content/notes/bayesianstatistics/week2.md b/content/notes/bayesianstatistics/week2.md new file mode 100644 index 0000000..54b2a6f --- /dev/null +++ b/content/notes/bayesianstatistics/week2.md @@ -0,0 +1,537 @@ +Under the frequentest paradigm, you view the data as a random sample from some larger, potentially hypothetical population. We can then make probability statements i.e, long-run frequency statements based on this larger population. + +## Coin Flip Example (Central Limit Theorem) + +Let's suppose we flip a coin 100 times and we get 44 heads and 56 tails. +$$ +n = 100 +$$ +We can view these 100 flips as a random sample from a much larger infinite hypothetical population of flips from this coin. + +Let's say that each flip follows a Bournelli distribution with some probability p. In this case $p$ is unknown, but we're assuming it's fixed because we have a particular physical coin. + +We can ask what's our best estimate of the probability of getting a head, or an estimate of $p$. We can also ask about how confident we are about that estimate. + +Let's start by applying the Central Limit Theorem. The Central Limit Theorem states that the sum of 100 flips will follow approximately a Normal distribution with mean 100p and variance 100p(1-p) +$$ +\sum^n_{i=1}{x_i} \sim N(np, np(1-p)) +$$ + +$$ +\sum_{i = 1}^{100}{x_i} \sim N(100p, 100p(1-p)) +$$ + +By the properties of a Normal distribution, 95% of the time we'll get a result within 1.96 standard deviations of the mean. Our estimate is $100\hat{p}$ and our error is 1.96 times the standard deviation. +$$ +n\hat{p} \pm 1.96\sqrt{n\hat{p}(1-\hat{p})} +$$ + +$$ +100\hat{p} \pm 1.96\sqrt{100\hat{p}(1-\hat{p})} +$$ + +This is referred to as a Confidence Interval. Confidence Intervals are commonly abbreviated as CI. In our example $\hat{p} = \frac{44}{n} = \frac{44}{100}$. Therefore, the 95% Confidence Interval in the true number of heads after flipping a coin 100 times is: +$$ +100(.44) \pm 1.96\sqrt{100(.44)(1-.44)} +$$ + +$$ +44 \pm 1.96\sqrt{44(.56)} +$$ + +$$ +44\pm 1.96\sqrt{24.64} +$$ + +$$ +(34.27, 53.73) +$$ + +We can divide this by 100 to get the 95% Confidence Interval for $p$ +$$ +(0.34, 0.53) +$$ +Let's step back and ask, what does it mean when I say we're 95% confident? + +Under the frequentest paradigm, what this means is we have to think back to our infinite hypothetical sequence of events. So if we were to repeat this trial an infinite number of times, or an arbitrary large number of times. Each time we create a confidence interval based on the data we observe, than on average 95% of the intervals we make will contain the true value of p. + +On the other hand, we might want to know something about this particular interval. Does this interval contain the true p? What's the probability that this interval contains a true p? Well, we don't know for this particular interval. But under the frequentest paradigm, we're assuming that there is a fixed answer for p. Either p is in that interval or it's not in that interval. The probability that p is in that interval is either 0 or 1. + +## Example: Heart Attack Patients (Maximum Likelihood) + +Consider a hospital where 400 patients are admitted over a month for heart attacks, and a month later 72 of them have died and 328 of them have survived. + +We can ask, what's our estimate of the mortality rate? + +Under the frequentest paradigm, we must first establish our reference population. What do we think our reference population is here? One possibility is we could think about heart attack patients in the region. + +Another reference population we can think about is heart attack patients that are admitted to this hospital, but over a longer period of time. + +Both of these might be reasonable attempts, but in this case our actual data are not random sample from either of those populations. We could sort of pretend they are and move on, or we could also try to think harder about what a random sample situation might be. We can think about all the people in the region who might possibly have a heart attack and might possibly get admitted to this hospital. + +It's a bit of an odd hypothetical situation, and so there are some philosophical issues with the setup of this whole problem with the frequentest paradigm, In any case, let's forge forward and think about how we might do some estimation. + +Moving on, we can say each patient comes from a Bernoulli distribution with an unknown parameter $\theta$. +$$ +Y_i \sim B(\theta) +$$ + +$$ +P(Y_i = 1) = \theta +$$ + +In this case, let's call the "success" a mortality. + +The probability density function for the entire set of data we can write in vector form. Probability of all the Y's take some value little y given a value of theta. +$$ +P(Y = y | \theta) = P(Y_1 = y_1, Y_2, = y_2,\dots, Y_n=y_n|\theta) +$$ +*Since we're viewing these as independent events*, then the probability of each of these individual ones we can write in product notation. +$$ +P(Y = y | \theta) = P(Y_1 = y_1|\theta)\dots P(Y_n = y_n | \theta) +$$ + +$$ +P(Y = y | \theta) = \prod_{i = 1}^n{P(Y_i =y_i | \theta)} = \prod_{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})} +$$ + +This is the probability of observing the actual data that we collected, conditioned on a value of the parameter $\theta$. We can now think about this expression as a function of theta. This is a concept of a likelihood. +$$ +L(\theta|y) = \prod_{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})} +$$ +It looks like the same function, but here it is a function of y given $\theta$. And now we're thinking of it as a function of $\theta$ given y. + +This is not a probability distribution anymore, but it is still a function for $\theta$. + +One we to estimate $\theta$ is that we choose the $\theta$ that gives us the largest value of the likelihood. It makes the data the most likely to occur for the particular data we observed. + +This is referred to as the maximum likelihood estimate (MLE), + +We're trying to find the $\theta$ that maximizes the likelihood. + +In practice, it's usually easier to maximize the natural logarithm of the likelihood, commonly referred to as the log likelihood. +$$ +\mathcal{L}(\theta) = \log{L(\theta|y)} +$$ +Since the logarithm is a monotonic function, if we maximize the logarithm of the function, we also maximize the original function. +$$ +\mathcal{L(\theta)} = \log{\prod_{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})}} +$$ + +$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{\log{(\theta^{y_i}(1-\theta)^{1-y_i})}} +$$ + +$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{(\log{(\theta^{y_i}}) + \log{(1-\theta)^{1-y_i}})} +$$ + +$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{(y_i\log{\theta} + (1 - y_i)\log{(1-\theta)})} +$$ + +$$ +\mathcal{L}(\theta) = \log{\theta}\sum_{i = 1}^n{y_i} + \log{(1-\theta)}\sum_{i = 1}^n{(1-y_i)} +$$ + +How do we find the theta that maximizes this function? Recall from calculus that we can maximize a function by taking the derivative and setting it equal to 0. +$$ +\mathcal{L}^\prime(\theta) = \frac{1}{\theta}\sum{y_i} - \frac{1}{1-\theta}\sum{(1 - y_i)} +$$ +Now we need to set it equal to zero and solve for $\hat{\theta}$ +$$ +\frac{\sum{y_i}}{\hat{\theta}} = \frac{\sum{(1-y_i)}}{1-\hat{\theta}} +$$ + +$$ +\hat{\theta}\sum{(1-y_i)} = (1-\hat{\theta})\sum{y_i} +$$ + +$$ +\hat{\theta}\sum{(1-y_i)} + \hat{\theta}\sum{y_i} = \sum{y_i} +$$ + +$$ +\hat{\theta}(\sum^n{(1 - y_i + y_i)}) = \sum{y_i} +$$ + +$$ +\hat{\theta} = \frac{1}{n}\sum{y_i} = \hat{p} = \frac{72}{400} = 0.18 +$$ + +Maximum likelihood estimators have many desirable mathematical properties. They're unbiased, they're consistent, and they're invariant. + +In general, under certain regularity conditions, we can say that the MLE is approximately normally distributed with mean at the true value of $\theta$ and the variance $\frac{1}{I(\hat{\theta})}$ where $I(\hat{\theta})$ is the Fisher information at the value of $\hat{\theta}$. The Fisher information is a measure of how much information about $\theta$ is in each data point. +$$ +\hat{\theta} \sim N(\theta, \frac{1}{I(\hat{\theta})}) +$$ +For a Bernoulli random variable, the Fisher information turns out to be +$$ +I(\theta) = \frac{1}{\theta(1-\theta)} +$$ +So the information is larger, when theta is near zero or near one, and it's the smallest when theta is near one half. + +This makes sense, because if you're flipping a coin, and you're getting a mix of heads and tails, that tells you a little bit less than if you're getting nearly all heads or nearly all tails. + +## Exponential Likelihood Example + +Let's say $X_i$ are distributed so +$$ +X_i \sim Exp(\lambda) +$$ +Let's say the data is independent and identically distributed, therefore making the overall density function +$$ +f(x|\lambda) = \prod_{i = 1}^n{\lambda e^{-\lambda x_i}} +$$ + +$$ +f(x|\lambda) = \lambda^ne^{-\lambda \sum{x_i}} +$$ + +Now the likelihood function is +$$ +L(\lambda|x) = \lambda^n e^{-\lambda \sum{x_i}} +$$ + +$$ +\mathcal{L}(\lambda) = n\ln{\lambda} - \lambda\sum{x_i} +$$ + +Taking the derivative +$$ +\mathcal{L}^\prime(\lambda) = \frac{n}{\lambda} - \sum{x_i} +$$ +Setting this equal to zero +$$ +\frac{n}{\hat{\lambda}} =\sum{x_i} +$$ + +$$ +\hat{\lambda} = \frac{n}{\sum{x_i}} = \frac{1}{\bar{x}} +$$ + +## Uniform Distribution + +$$ +X_i \sim U[0, \theta] +$$ + +$$ +f(x|\theta) = \prod_{i = 1}^n{\frac{1}{\theta}I_{0 \le x_i \le \theta}} +$$ + +Combining all the indicator functions, for this to be a 1, each of these has to be true. These are going to be true if all the observations are bigger than 0, as in the minimum of the x is bigger than or equal to 0. The maximum of the x's is also less than or equal to $\theta$. +$$ +L(\theta|x) = \theta^{-1} I_{0\le min(x_i) \le max(x_i) \le \theta} +$$ + +$$ +L^\prime(\theta) = -n\theta^{-(n + 1)}I_{0 \le min(x_i) \le max(x_i)\le \theta} +$$ + +So now we can ask, can we set this equal to zero and solve for $\theta$? Well it turns out, this is not equal to zero for any $\theta$ positive value. We need $\theta$ to be strictly larger than zero. + +However, we can also note that for $\theta$ positive, this will always be negative. The derivative is negative, that says this is a decreasing function. So this funciton will be maximized when we pick $\theta$ as small as possible. What's the smallest possible value of $\theta$ we can pick? Well we need in particular for $\theta$ to be larger than all of the $X_i$ . And so, the maximum likelihood estimate is the maximum of $X_i$ +$$ +\hat{\theta} = max(x_i) +$$ + +## Products of Indicator Functions + +Because 0 * 1 = 0, the product of indicator functions can be combined into a single indicator function with a modified condition. + +**Example**: $I_{x < 5} * I_{x \ge 0} = I_{0 \le x < 5}$ + +**Example**: $\prod_{i = 1}^n{I_{x_i < 2}} = I_{x_i < 2 for all i} = I_{max(x_i) < 2}$ + +## Introduction to R + +R has some nice functions that one can use for analysis + +`mean(z)` gives the mean of some row vector $z$ + +`var(z)` reports the variance of some row vector + +`sqrt(var(z))` gives the standard deviation of some row vector + +`seq(from=0.1, to = 0.9, by = 0.1)` creates a vector that starts from $0.1$ and goes to $0.9$ incrementing by $0.1$ + +```R +seq(from=0.1, to = 0.9, by = 0.1) +[1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 +seq(1, 10) +[1] 1 2 3 4 5 6 7 8 9 10 +``` + +`names(x)` gives the names of all the columns in the dataset. + +```R +names(trees) +[1] "Girth" "Height" "Volume" +``` + +`hist(x)` provides a histogram based on a vector + +The more general `plot` function tries to guess at which type of plot to make. Feeding it two numerical vectors will make a scatter plot. + +The R function `pairs` takes in a data frame and tries to make all possible Pairwise scatterplots for the dataset. + +The `summary` command gives the five/six number summary (minimum, first quartile, median, mean, third quartile, maximum) + +## Plotting the likelihood function in R + +Going back to the hospital example + +```R +## Likelihood function +likelihood = function(n, y, theta) { + return(theta^y * (1 - theta)^(n - y)) +} +theta = seq(from = 0.01, to = 0.99, by = 0.01) +plot(theta, likelihood(400, 72, theta)) +``` + +You can also do this with log likelihoods. This is typically more numerically stable to compute + +```R +loglike = function(n, y, theta) { + return(y * log(theta) + (n - y) * log(1 - theta)) +} +plot(theta, loglike(400, 72, theta)) +``` + +Having these plotted as points makes it difficult to see, let's plot it as lines + +```R +plot(theta, loglike(400, 72, theta), type = "l") +``` + + + +## Cumulative Distribution Function + +The cumulative distribution function (CDF) exists for every distribution. We define it as $F(x) = P(X \le x)$ for random variable $X$. + +If $X$ is discrete-valued, then the CDF is computed with summation $F(x) = \sum_{t = -\infty}^x {f(t)}$. where $f(t) = P(X = t)$ is the probability mass function (PMF) which we've already seen. + +If $X$ is continuous, the CDF is computed with an integral $F(x) = \int_{-\infty}^x{f(t)dt}$ + +The CDF is convenient for calculating probabilities of intervals. Let $a$ and $b$ be any real numbers with $a < b$. Then the probability that $X$ falls between $a$ and $b$ is equal to $P(a < X < b) = P(X \le b) - P(X \le a) = F(b) - F(a)$ + + + +## Quantile Function + +The CDF takes a value for a random variable and returns a probability. Suppose instead we start with a number between $0$ and $1$, which we call $p$, and we wish to find a value $x$ so that $P(X \le x) = p$. The value $x$ which satisfies this equation is called the $p$ quantile. (or $100p$ percentile) of the distribution of $X$. + + + +## Probability Distributions in R + +Each of the distributions introduced in Lesson 3 have convenient functions in R which allow you to evaluate the PDF/PMF, CDF, and quantile functions, as well as generate random samples from the distribution. To illustrate, Table I list these functions for the normal distribution + +| Function | What it does | +| -------------------- | ---------------------------------------- | +| `dnorm(x, mean, sd)` | Evaluate the PDF at $x$ (mean = $\mu$ and sd = $\sqrt{\sigma^2}$) | +| `pnorm(q, mean, sd)` | Evaluate the CDF at $q$ | +| `qnorm(p, mean, sd)` | Evaluate the quantile function at $p$ | +| `rnorm(n, mean, sd)` | Generate $n$ pseudo-random samples from the normal distribution | + +These four functions exist for each distribution where `d...` function evaluates the density/mass, `p...` evaluates the CDF, `q...` evaluates the quantile, and `r...` generates a sample. Table 2 lists the `d...` functions for some of the most popular distributions. The `d` can be replaced with `p`, `q`, or `r` for any of the distributions, depending on what you want to calculate. + +For details enter `?dnorm` to view R's documentation page for the Normal distribution. As usual , replace the `norm` with any distribution to read the documentation for that distribution. + +| Distribution | Function | Parameters | +| ---------------------- | -------------------------- | ------------------------------------ | +| $Binomial(n,p)$ | `dbinom(x, size, prob)` | size = $n$, prob = $p$ | +| $Poisson(\lambda)$ | `dpois(x, lambda)` | lambda = $\lambda$ | +| $Exp(\lambda)$ | `dexp(x, rate)` | rate = $\lambda$ | +| $Gamma(\alpha, \beta)$ | `dgamma(x, shape, rate)` | shape = $\alpha$, rate = $\beta$ | +| $Uniform(a, b)$ | `dunif(x, min, max)` | min = $a$, max = $b$ | +| $Beta(\alpha, \beta)$ | `dbeta(x, shape1, shape2)` | shape1 = $\alpha$, shape2 = $\beta$ | +| $N(\mu, \sigma^2)$ | `dnorm(x, mean, sd)` | mean = $\mu$, sd = $\sqrt{\sigma^2}$ | +| $t_v$ | `dt(x, df)` | df = $v$ | + +## Two Coin Example + +Suppose your brother has a coin which you know to be loaded so that it comes up heads 70% of the time. He then comes to you with some coin, you're not sure which one and he wants to make a bet with you. Betting money that it's going to come up heads. + +You're not sure if it's the loaded coin or if it's just a fair one. So he gives you a chance to flip it 5 times to check it out. + +You flip it five times and get 2 heads and 3 tails. Which coin do you think it is and how sure are you about that? + +We'll start by defining the unknown parameter $\theta$, this is either that the coin is fair or it's a loaded coin. +$$ +\theta = \{fair ,loaded\} +$$ + +$$ +X \sim Bin(5, ?) +$$ + +$$ +f(x|\theta) = \begin{cases} + {5 \choose x}(\frac{1}{2})^5 & \theta = fair \\ + {5 \choose x} (.7)^x (.3)^{5 - x} & \theta = loaded\\ + \end{cases} +$$ + +We can also rewrite $f(x|\theta)$ with indicator functions +$$ +f(x|\theta) = {5\choose x}(.5)^5I_{\{\theta= fair\}} + {5 \choose x}(.7)^x(.3)^{5 - x}I_{\{\theta = loaded\}} +$$ +In this case, we observed that $x = 2$ +$$ +f(\theta | x = 2) = \begin{cases} + 0.3125 & \theta = fair \\ + 0.1323 & \theta = loaded +\end{cases} +$$ +MLE $\hat{\theta} = fair$ + +That's a good point estimate, but then how do we answer the question, how sure are you? + +This is not a question that's easily answered in the frequentest paradigm. Another question is that we might like to know what is the probability that theta equals fair, give, we observe two heads. +$$ +P(\theta = fair|x = 2) = ? +$$ +In the frequentest paradigm, the coin is a physical quantity. It's a fixed coin, and therefore it has a fixed probability of coining up heads. It is either the fair coin, or it's the loaded coin. +$$ +P(\theta = fair) = \{0,1\} +$$ + +### Bayesian Approach to the Problem + +An advantage of the Bayesian approach is that it allows you to easily incorporate prior information, when you know something in advance of the looking at the data. This is difficult to do under the Frequentest paradigm. + +In this case, we're talking about your brother. You probably know him pretty well. So suppose you think that before you've looked at the coin, there's a 60% probability that this is the loaded coin. + +This case, we put this into our prior. Our prior is that the probability the coin is loaded is 0.6. We can update our prior with the data to get our posterior beliefs, and we can do this using the bayes theorem. + +Prior: $P(loaded) = 0.6$ +$$ +f(\theta|x) = \frac{f(x|\theta)f(\theta)}{\sum_\theta{f(x|\theta)f(\theta)}} +$$ + +$$ +f(\theta|x) = \frac{{5\choose x} [(\frac{1}{2})^5(.4)I_{\{\theta = fair\}} + (.7)^x (.3)^{5-x}(.6)I_{\{\theta = loaded\}} ] } +{{5\choose x} [(\frac{1}{2})^5(.4) + (.7)^x (.3)^{5-x}(0.6) ] } +$$ + +$$ +f(\theta|x=2)= \frac{0.0125I_{\{\theta=fair\}} + 0.0079I_{\{\theta=loaded\}} }{0.0125+0.0079} +$$ + +$$ +f(\theta|x=2) = 0.612I_{\{\theta=fair\}} + 0.388I_{\{\theta = loaded\}} +$$ + +As you can see in the calculation here, we have the likelihood times the prior in the numerator, and in the denominator, we have a normalizing constant, so that when we divide by this, we'll get answer that add up to one. These numbers match exactly in this case, because it's a very simple problem. But this is a concept that goes on, what's in the denominator here is always a normalizing constant. +$$ +P(\theta = loaded | x = 2) = 0.388 +$$ +This here updates our beliefs after seeing some data about what the probability might be. + +We can also examine what would happen under different choices of prior. +$$ +P(\theta = loaded) = \frac{1}{2} \implies P(\theta = loaded | x = 2) = 0.297 +$$ + +$$ +P(\theta = loaded) = 0.9 \implies P(\theta = loaded | x = 2) = 0.792 +$$ + +In this case, the Bayesian approach is inherently subjective. It represents your own personal perspective, and this is an important part of the paradigm. If you have a different perspective, you will get different answers, and that's okay. It's all done in a mathematically vigorous framework, and it's all mathematically consistent and coherent. + +And in the end, we get results that are interpretable + +## Continuous Bayes + +$$ +f(\theta | y) = \frac{f(y | \theta)f(\theta)}{f(y)} = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} = \frac{likelihood * prior}{normalization} \propto likelihood * prior +$$ + +In practice, sometimes this integral can be a pain to compute. And so, we may work with looking at saying this is proportional to the likelihood times the prior. And if we can figure out what this looks like and just put the appropriate normalizing constant on at the end, we don't necessarily have to compute this integral. + + + +So for example, suppose we're looking at a coin and it has unknown probability $\theta$ of coming up heads. Suppose we express ignorance about the value of $\theta$ by assigning it a uniform distribution. +$$ +\theta \sim U[0, 1] +$$ + +$$ +f(\theta) = I_{\{0 \le \theta\le 1\}} +$$ + +$$ +f(\theta | y = 1) = \frac{\theta^1(1-\theta)^0I_{\{0 \le \theta\le1\}}}{\int_{-\infty}^\infty{\theta^1(1-\theta)^0I_{\{0\le \theta \le 1\}}}} +$$ + +$$ +f(\theta | y = 1) = \frac{\theta I_{\{0\le\theta\le1\}}}{\int_0^1{\theta d\theta}} = 2\theta I_{\{0\le\theta\le1\}} +$$ + +Now if we didn't want to take the integral we could've done this approach +$$ +f(\theta | y) \propto f(y|\theta)f(\theta) \propto \theta I_{\{0\le\theta\le1\}} +$$ +Which then we need to find the constant such that it's a proper PMF. In this case, it's $2$. + +Since it's a proper PMF, we can perform interval probabilities as well. This is called Posterior interval estimates. +$$ +P(0.025 < \theta < 0.975) = \int_{0.025}^{0.975}{2\theta d \theta} = (0.975)^2 - (0.025)^2 = 0.95 +$$ + +$$ +P(\theta > 0.05) = 1 - (0.05)^2 = 0.9975 +$$ + +These are the sort of intervals we would get from the prior and asking about what their posterior probability is. + +In other cases, we may want to ask, what is the posterior interval of interest? What's an interval that contains 95% of posterior probability in some meaningful way? This would be equivalent then to a frequentest confidence interval. We can do this in several different ways, 2 main ways that we make Bayesian Posterior intervals or credible intervals are equal-tailed intervals and highest posterior density intervals. + +## Equal-tailed Interval + +In the case of an equal-tailed interval, we put the equal amount of probability in each tail. So to make a 95% interval we'll put 0.025 in each tail. + +To be able to do this, we're going to have to figure out what the quantiles are. So we're going to need some value, $q$, so that +$$ +P(\theta < q | Y = 1) = \int_0^9{2\theta d\theta} = q^2 +$$ + +$$ +P(\sqrt{0.025} < \theta < \sqrt{0.975}) = P(0.158 < \theta < 0.987) = 0.95 +$$ + +This is an equal tailed interval in that the probability that $\theta$ is less than 0.18 is the same as the probability that $\theta$ is greater than 0.987. We can say that under the posterior, there's a 95% probability that $\theta$ is in this interval. + +## Highest Posterior Density (HPD) + +Here we want to ask where in the density function is it highest? Theoretically this will be the shortest possible interval that contains the given probability, in this case a 95% probability. +$$ +P(\theta > \sqrt{0.05} | Y = 1) = P(\theta > 0.224 | Y = 1) = 0.95 +$$ +This is the shortest possible interval, that under the posterior has a probability 0.95. it's $\theta$ going from 0.224 up to 1. + + + +The posterior distribution describes our understanding of our uncertainty combinbing our prior beliefs and the data. It does this with a probability density function, so at the end of teh day, we can make intervals and talk about probabilities of data being in the interval. + +This is different from the frequentest approach, where we get confidence intervals. But we can't say a whole lot about the actual parameter relative to the confidence interval. We can only make long run frequency statements about hypothetical intervals. + +In this case, we can legitimately say that the posterior probability that $\theta$ is bigger than 0.05 is $0.9975$. We can also say that we believe there's a 95% probability that $\theta$ is in between 0.158 and 0.987. + + + +Bayesians represent uncertainty with probabilities, so that the coin itself is a physical quantity. It may have a particular value for $\theta$. + +It may be fixed, but because we don't know what that value is, we represent our uncertainty about that value with a distribution. And at the end of the day, we can represent our uncertainty, collect it with the data, and get a posterior distribution and make intuitive statements. + + + +#### + +Frequentest confidence intervals have the interpretation that "If you were to repeat many times the process of collecting data and computing a 95% confidence interval, then on average about 95% of those intervals would contain the true parameter value; however, once you observe data and compute an interval the true value is either in the interval or it is not, but you can't tell which." + +Bayesian credible intervals have the interpretation that "Your posterior probability that the parameter is in a 95% credible interval is 95%." \ No newline at end of file diff --git a/content/notes/bayesianstatistics/week3.md b/content/notes/bayesianstatistics/week3.md new file mode 100644 index 0000000..cb1c1fc --- /dev/null +++ b/content/notes/bayesianstatistics/week3.md @@ -0,0 +1,409 @@ +How do we choose a prior? + +Our prior needs to represent our personal perspective, beliefs, and our uncertainties. + +Theoretically, we're defining a cumulative distribution function for the parameter +$$ +\begin{cases} +P(\theta \le c) & c \in \mathbb{R} +\end{cases} +$$ +This is true for an infinite number of possible sets. This isn't practical to do, and it would be very difficult to do coherently so that all the probabilities were consistent. + +In practice, we work with a convenient family that's sufficiently flexible such that a member of a family represents our beliefs. + +Generally if one has enough data, the information in the data will overwhealm the information in the prior. And so, the prior is not particularly important in terms of what you get for the posterior. Any reasonable choice of prior will lead to approximately the same posterior. However, there are some things that can go wrong. + +## Example of Bad Prior + +Suppose we chose a prior that says the probability of $P(\theta = \frac{1}{2}) = 1$ + +And thus, the probability of $\theta$ equaling any other value is $0$. If we do this, our data won't make a difference since we only put a probability of $1$ at a single point. +$$ +f(\theta|y) \propto f(y|\theta)f(\theta) = f(\theta) = \delta(\theta) +$$ + +In the basic context, events with prior probability of zero have a posterior probability of zero. Events with a prior probability of one, have a posterior probability of one. + +Thus a good Bayesian will not assign probability of zero or one to any event that has already occurred or already known not to occur. + +## Calibration + +A useful concept in terms of choosing priors is that of the calibration of predictive intervals. + +If we make an interval where we're saying we predict 95% of new data points will occur in this interval. It would be good if in reality 95% of new data points actually did fall in that interval. + +How do we calibrate to reality? This is actually a frequentest concept but this is important for practical statistical purposes that our results reflect reality. + +We can compute a predictive interval, this is an interval such that 95% of new observations are expected to fall into it. It's an interval for the **data** rather than an interval for $\theta$ +$$ +f(y) = \int{f(y|\theta)f(\theta)d\theta} = \int{f(y, \theta)d\theta} +$$ +Where $f(y,\theta)$ is the joint density of Y and $\theta$. + +This is the prior predictive before any data is observed. + +**Side Note:** From this you can say that $f(y, \theta) = f(y|\theta)f(\theta)$ + +## Binomial Example + +Suppose we're going to flip a coin ten times and count the number of heads we see. We're thinking about this in advance of actually doing it, so we're interested in the predictive distribution. How many heads do we predict we're going to see? +$$ +X = \sum_{i = 1}^{10}{Y_i} +$$ +Where $Y_i$ is each individual coin flip. + +If we think that all possible coins or all possible probabilities are equally likely, then we can put a prior for $\theta$ that's flat over the interval from 0 to 1. +$$ +f(\theta) = I_{\{0 \le \theta \le 1\}} +$$ + +$$ +f(x) = \int{f(x|\theta)f(\theta)d\theta} = \int_0^1{\frac{10!}{x!(10-x)!}\theta^x(1-\theta)^{10 -x}(1)d\theta} +$$ + +Note that because we're interested in $X$ at the end, it's important that we distinguish between a binomial density and a Bernoulli density. Here we just care about the total count rather than the exact ordering which would be Bernoulli's + +For most of the analyses we're doing, where we're interested in $\theta$ rather than x, the binomial and the Bernoulli are interchangeable because the part in here that depends on $\theta$ is the same. + +To solve this integral let us recall some facts +$$ +n! = \Gamma(n + 1) +$$ + +$$ +Z \sim Beta(\alpha, \beta) +$$ + +$$ +f(z) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha) \Gamma(\beta)}z^{\alpha - 1}(1-z)^{\beta - 1} +$$ + +Let us rewrite $f(x)$ +$$ +f(x) = \int_0^1{\frac{\Gamma(11)}{\Gamma(x + 1)\Gamma(11 - x)}\theta^{(x + 1)-1}(1-\theta)^{(11-x)-1}d\theta} +$$ + +$$ +f(x) = \frac{\Gamma(11)}{\Gamma(12)}\int_0^1{\frac{\Gamma(12)}{\Gamma(x + 1)\Gamma(11 - x)}\theta^{(x + 1)-1}(1-\theta)^{(11-x)-1}d\theta} +$$ + +The integral above is a beta density, all integrals of valid beta densities equals to one. +$$ +f(x) = \frac{\Gamma(11)}{\Gamma(12)} = \frac{10!}{11!} = \frac{1}{11} +$$ +For $x \in {0, 1, 2, \dots, 10}$ + +Thus we see that if we start with a uniform prior, we then end up with a discrete uniform predictive density for $X$. If all possible probabilities are equally likely, then all possible $X$ outcomes are equally likely. + +## Posterior Predictive Distribution + +What about after we've observed data? What's our posterior predictive distribution? + +Going from the previous example, let us observe after one flip that we got a head. We want to ask, what's our predictive distribution for the second flip, given we saw a head on the first flip. +$$ +f(y_2|y_1) = \int{f(y_2|\theta,y_1)f(\theta|y_1)}d\theta +$$ +We're going to assume that $Y_2$ is independent of $Y_1$. Therefore, +$$ +f(y_2 |y_1) = \int{f(y_2|\theta)f(\theta|y_1)d\theta} +$$ +Suppose we're thinking of a uniform distribution for $\theta$ and we observe the first flip is a heads. What do we predict for the second flip? + +This is no longer going to be a uniform distribution like it was before, because we have some data. We're going to think it's more likely that we're going to get a second head. We think this because since we observed a head $\theta$ is now likely to be at least $\frac{1}{2}$ possibly larger. +$$ +f(y_2 | Y_1 = 1) = \int_0^1{\theta^{y_2}(1-\theta)^{1-y_2}2\theta d\theta} +$$ + +$$ +f(y_2|Y_1 = 1) = \int_0^1{2\theta^{y_2 + 1}(1-\theta)^{1-y_2}d\theta} +$$ + +We could work this out in a more general form, but in this case, $Y_2$ has to take the value $0$ or $1$. The next flip is either going to be heads or tails so it's easier to just plop in a particular example. +$$ +P(Y_2 = 1|Y_1 = 1) = \int_0^1{2\theta^2d\theta} = \frac{2}{3} +$$ + +$$ +P(Y_2 = 0 | Y_1 = 1) = 1 - P(Y_2 = 1 | Y_1 = 1) = 1 - \frac{2}{3} = \frac{1}{3} +$$ + +We can see here that the posterior is a combination of the information in the prior and the information in the data. In this case, our prior is like having two data points, one head and one tail. + +Saying we have a uniform prior for $\theta$ is equivalent in an information sense as saying we have observed one head and one tail. + +So then when we observe one head, it's like we now have seen two heads and one tail. So our predictive distribution for the second flip says if we have two heads and one tail, then we have a $\frac{2}{3}$ probability of getting another head and a $\frac{1}{3}$ probability of getting another tail. + +## Binomial Likelihood with Uniform Prior + +Likelihood of y given theta is +$$ +f(y|\theta) = \theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}} +$$ + +Our prior for theta is just a uniform distribution +$$ +f(\theta) = I_{\{0 \le \theta \le 1\}} +$$ +Thus our posterior for $\theta$ is +$$ +f(\theta | y) = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} = \frac{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}} I_{\{0 \le \theta \le 1\}}}{\int_0^1{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}} I_{\{0 \le \theta \le 1\}}d\theta}} +$$ +Recalling the form of the beta distribution we can rewrite our posterior as +$$ +f(\theta | y) = \frac{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}} I_{\{0 \le \theta \le 1\}}}{\frac{\Gamma(\sum{y_i} + 1)\Gamma(n - \sum{y_i} + 1)}{\Gamma(n + 2)}\int_0^1{\frac{\Gamma(n + 2)}{\Gamma(\sum{y_i} + 1)\Gamma(n - \sum{y_i} + 1)}\theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}}d\theta}} +$$ +Since the beta density integrates to $1$, we can simplify this as +$$ +f(\theta | y) = \frac{\Gamma(n + 2)}{\Gamma(\sum{y_i}+ 1)\Gamma(n - \sum{y_i}+ 1)}\theta^{\sum{y_i}}(1-\theta)^{n-\sum{y_i}}I_{\{0 \le \theta \le 1\}} +$$ +From here we can see that the posterior follows a beta distribution +$$ +\theta | y \sim Beta(\sum{y_i} + 1, n - \sum{y_i} + 1) +$$ + +## Conjugate Priors + +The uniform distribution is $Beta(1, 1)$ + +Any beta distribution is conjugate for the Bernoulli distribution. Any beta prior will give a beta posterior. +$$ +f(\theta) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}\theta^{\alpha - 1}(1-\theta)^{\beta -1}I_{\{0 \le \theta \le 1\}} +$$ + +$$ +f(\theta | y) \propto f(y|\theta)f(\theta) = \theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}}\frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}\theta^{\alpha - 1}(1 - \theta)^{\beta - 1}I_{\{0 \le \theta \le 1\}} +$$ + +$$ +f(y|\theta)f(\theta) \propto \theta^{\alpha + \sum{y_i}-1}(1-\theta)^{\beta + n - \sum{y_i} - 1} +$$ + +Thus we see that this is a beta distribution +$$ +\theta | y \sim Beta(\alpha + \sum{y_i}, \beta + n - \sum{y_i}) +$$ +When $\alpha$ and $\beta$ is one like in the uniform distribution, then we get the same result as earlier. + + + +This whole process where we choose a particular form of prior that works with a likelihood is called using a conjugate family. + +A family of distributions is referred to as conjugate if when you use a member of that family as a prior, you get another member of that family as your posterior. + +The beta distribution is conjugate for the Bernoulli distribution. It's also conjugate for the binomial distribution. The only difference in the binomial likelihood is that there is a combinatoric term. Since that does not depend on $\theta$, we get the same posterior. + +We often use conjugate priors because they make life much more simpler, sticking to conjugate families allows us to get closed form solutions easily. + +If the family is flexible enough, then you can find a member of that family that closely represents your beliefs. + +## Posterior Mean and Effect Size + +Returning to the beta posterior model it is clear how both the prior and the data contribute to the posterior. + +We can say that the effect size of the prior is $\alpha + \beta$ + +Recall that the expected value or mean of a beta distribution is $\frac{\alpha}{\alpha + \beta}$ + +Therefore we can derive the posterior mean as +$$ +posterior_{mean} = \frac{\alpha + \sum{y_i}}{\alpha + \sum{y_i}+\beta + n - \sum{y_i}}= \frac{\alpha+\sum{y_i}}{\alpha + \beta + n} +$$ +We can further decompose this as +$$ +posterior_{mean} = \frac{\alpha + \beta}{\alpha + \beta + n}\frac{\alpha}{\alpha + \beta} + \frac{n}{\alpha + \beta + n}\frac{\sum{y_i}}{n} +$$ +We can describe this as the (prior weight * prior mean) + (data weight * data mean) + +The posterior mean is a weighted average of the prior mean and the data mean. + +This effective sample size gives you an idea of how much data you would need to make sure that your prior doesn't have much influence on your posterior. + +If $\alpha + \beta$ is small compared to $n$ then the posterior will largely just be driven by the data. If $\alpha + \beta$ is large relative to $n$ then the posterior will be largely driven by the prior. + +We can make a 95% credible interval using our posterior distribution for $\theta$. We can find an interval that actually has 95% probability of containing $\theta$. + +Using Bayesian Statistics we can chain together dong a sequential update every time we get new data. We can get a new posterior, and we just use our previous posterior as a prior to do another update using Baye's theorem. + +## Data Analysis Example in R + +Suppose we're giving two students a multiple-choice exam with 40 questions, where each question has four choices. We don't know how much the students have studied for this exam, but we think that they'll do better than just guessing randomly + +1) What are the parameters of interest? + +The parameters of interests are $\theta_1 = true$ the probability that the first student will answer a question correctly, $\theta_2 = true$ the probability that the second student will answer a question correctly. + +2) What is our likelihood? + +The likelihood is $Binomial(40, \theta)$, if we assume that each question is independent and that the probability a student gets each question right is the same for all questions for that student. + +3) What prior should we use? + +The conjugate prior is a beta prior. We can plot the density with `dbeta` + +```R +theta = seq(from = 0, to = 1, by = 0.1) +# Uniform +plot(theta, dbeta(theta, 1, 1), type = 'l') +# Prior mean 2/3 +plot(theta, dbeta(theta, 4, 2), type = 'l') +# Prior mean 2/3 but higher effect size (more concentrated at mean) +plot(theta, dbeta(theta, 8, 4), type = 'l') +``` + +4 ) What are the prior probabilities $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$? + +```R +1 - pbeta(0.25, 8, 4) +#[1] 0.998117 +1 - pbeta(0.5, 8, 4) +#[1] 0.8867188 +1 - pbeta(0.8, 8, 4) +#[1] 0.16113392 +``` + + + +5) Suppose the first student gets 33 questions right. What is the posterior distribution for $\theta_1$? $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$? What is the 95% posterior credible interval for $\theta_1$? +$$ +Posterior \sim Beta(8 + 33, 4 + 40 - 33) = Beta(41, 11) +$$ +With a posterior mean of $\frac{41}{41+11} = \frac{41}{52}$ + +We can plot the posterior distribution with the prior + +```R +plot(theta, dbeta(theta, 41, 11), type = 'l') +lines(theta, dbeta(theta, 8 ,4), lty = 2) #Dashed line for prior +``` + +Posterior probabilities + +```R +1 - pbeta(0.25, 41, 11) +#[1] 1 +1 - pbeta(0.5, 41, 11) +#[1] 0.9999926 +1 - pbeta(0.8, 41, 11) +#[1] 0.4444044 +``` + +Equal tailed 95% credible interval + +```R +qbeta(0.025, 41, 11) +#[1] 0.6688426 +qbeta(0.975, 41, 11) +#[1] 0.8871094 +``` + +95% confidence that $\theta_1$ is between 0.67 and 0.89 + + + +6) Suppose the second student gets 24 questions right. What is the posterior distribution for $\theta_2$? $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$? What is the 95% posterior credible interval for $\theta_2$ +$$ +Posterior \sim Beta(8 + 24, 4 + 40 - 24) = Beta(32, 20) +$$ +With a posterior mean of $\frac{32}{32+20} = \frac{32}{52}$ + +We can plot the posterior distribution with the prior + +```R +plot(theta, dbeta(theta, 32, 20), type = 'l') +lines(theta, dbeta(theta, 8 ,4), lty = 2) #Dashed line for prior +``` + +Posterior probabilities + +```R +1 - pbeta(0.25, 32, 20) +#[1] 1 +1 - pbeta(0.5, 32, 20) +#[1] 0.9540427 +1 - pbeta(0.8, 32, 20) +#[1] 0.00124819 +``` + +Equal tailed 95% credible interval + +```R +qbeta(0.025, 32, 20) +#[1] 0.4808022 +qbeta(0.975, 32, 20) +#[1] 0.7415564 +``` + +95% confidence that $\theta_1$ is between 0.48 and 0.74 + + + +7) What is the posterior probability that $\theta_1 > \theta_2$? i.e., that the first student has a better chance of getting a question right than the second student? + +Estimate by simulation: draw 1,000 samples from each and see how often we observe $\theta_1 > \theta_2$ + +```R +theta1 = rbeta(100000, 41, 11) +theta2 = rbeta(100000, 32, 20) +mean(theta1 > theta2) +#[1] 0.975 +``` + +## Poisson Data (Chocolate Chip Cookie Example) + +In mass produced chocolate chip cookies, they make a large amount of dough. They mix in a large number of chips, mix it up really well and then chunk out individual cookies. In this process, the number of chips per cookie approximately follow a Poisson distribution. + +If we were to assume that chips have no volume, then this would be exactly a Poisson process and follow exactly a Poisson distribution. In practice, however, chips aren't that big so they follow approximately a Poisson distribution for the number of chips per cookie. +$$ +Y_i \sim Poisson(\lambda) +$$ + +$$ +f(y|\lambda) = \frac{\lambda^{\sum{y_i}}e^{-n\lambda}}{\prod_{i = 1}^n{y_i!}} +$$ + +This is for $\lambda > 0$ + +What type of prior should we put on $\lambda$? It would be convenient if we could put a conjugate prior. What distribution looks like lambda raised to a power and e raised to a negative power? + +For this, we're going to use a Gamma prior. +$$ +\lambda \sim \Gamma(\alpha, \beta) +$$ + +$$ +f(\lambda) = \frac{\beta^\alpha}{\Gamma(\alpha)}\lambda^{\alpha - 1}e^{-\beta\lambda} +$$ + +$$ +f(\lambda | y) \propto f(y|\lambda)f(\lambda) \propto \lambda^{\sum{y_i}}e^{-n\lambda}\lambda^{\alpha - 1}e^{-\beta \lambda} +$$ + +$$ +f(\lambda | y) \propto \lambda^{\alpha + \sum{y_i} - 1}e^{-(\beta + n)\lambda} +$$ + +Thus we can see that the posterior is a Gamma Distribution +$$ +\lambda|y \sim \Gamma(\alpha + \sum{y_i}, \beta + n) +$$ +The mean of Gamma under this parameterization is $\frac{\alpha}{\beta}$ + +The posterior mean is going to be +$$ +posterior_{mean} = \frac{\alpha + \sum{y_i}}{\beta + n} = \frac{\beta}{\beta + n}\frac{\alpha}{\beta} + \frac{n}{\beta + n}\frac{\sum{y_i}}{n} +$$ +As you can see here the posterior mean of the Gamma distribution is also the weighted average of the prior mean and the data mean. + +Let us present two strategies on how to choose our hyper parameters $\alpha$ and $\beta$ + +1. Think about the prior mean. For example, what do you think the number of chips per cookie on average is? + +After this, we need some other piece of knowledge to pin point both parameters. Here are some options. + +- What is your error on the number of chips per cookie? In other words, what do you think the standard deviation. Under the Gamma prior the standard deviation is $\frac{\sqrt{\alpha}}{\beta}$ +- What is the effective sample size $\beta$? How many units of information do you think we have in our prior versus our data points. + +2. In Bayesian Statistics, a vague prior refers to one that's relatively flat across much of the space. For a Gamma prior we can choose $\Gamma(\epsilon, \epsilon)$ where $\epsilon$ is small and strictly positive. + +This would create a distribution with a mean of 1 and a huge standard deviation across the whole space. Hence the posterior will be largely driven by the data and very little by the prior. \ No newline at end of file diff --git a/content/notes/bayesianstatistics/week4.md b/content/notes/bayesianstatistics/week4.md new file mode 100644 index 0000000..d2d4038 --- /dev/null +++ b/content/notes/bayesianstatistics/week4.md @@ -0,0 +1,617 @@ +## Exponential Data + +Suppose you're waiting for a bus that you think comes on average once every 10 minutes, but you're not sure exactly how often it comes. +$$ +Y \sim Exp(\lambda) +$$ +Your waiting time has a prior expectation of $\frac{1}{\lambda}$ + + + +It turns out the gamma distribution is conjugate for an exponential likelihood. We need to specify a prior, or a particular gamma in this case. If we think that the buses come on average every ten minutes, that's a rate of one over ten. +$$ +prior_{mean} = \frac{1}{10} +$$ +Thus, we'll want to specify a gamma distribution so that the first parameter divded by the second parameter is $\frac{1}{10}$ + +We can now think about our variability. Perhaps you specify +$$ +\Gamma(100, 1000) +$$ +This will indeed have a prior mean of $\frac{1}{10}$ and it'll have a standard deviation of $\frac{1}{100}$. If you want to have a rough estimate of our mean plus or minus two standard deviations then we have the following +$$ +0.1 \pm 0.02 +$$ +Suppose that we wait for 12 minutes and a bus arrives. Now you want to update your posterior for $\lambda$ about how often this bus will arrive. +$$ +f(\lambda | y) \propto f(y|\lambda)f(\lambda) +$$ + +$$ +f(\lambda | y) \propto \lambda e^{-\lambda y}\lambda^{\alpha - 1}e^{-\beta \lambda} +$$ + +$$ +f(\lambda | y) \propto \lambda^{(\alpha + 1) - 1}e^{-(\beta + y)\lambda} +$$ + +$$ +\lambda | y \sim \Gamma(\alpha + 1, \beta + y) +$$ + +Plugging in our particular prior gives us a posterior for $\lambda$ which is +$$ +\lambda | y \sim \Gamma(101, 1012) +$$ +Thus our posterior mean is going to be $\frac{101}{1012} Which is equal to 0.0998. + + + +This one observation doesn't contain a lot of data under this likelihood. When the bus comes and it takes 12 minutes instead of 10, it barely shifts our posterior mean up. One data point doesn't have a big impact here. + + + +## Normal/Gaussian Data + +Let's suppose the standard deviation or variance is known and we're only interested in learning about the mean. This is the situation that often arises in monitoring industrial production processes. +$$ +X_i \sim N(\mu, \sigma^2) +$$ +It turns out that the Normal distribution is conjugate for itself when looking for the mean parameter + +Prior +$$ +\mu \sim N(m_0,S_0^2) +$$ + +$$ +f(\mu |x ) \propto f(x|\mu)f(\mu) +$$ + +$$ +\mu | x \sim N(\frac{n\bar{x}/\sigma_0^2 + m_0/s_0^2}{n/\sigma_0^2 + 1/s_0^2}, \frac{1}{n/\sigma_0^2 + 1/s_0^2}) +$$ + +Let's look at the posterior mean +$$ +posterior_{mean} = \frac{n/\sigma_0^2}{n/\sigma_0^2 + 1/s_0^2}\bar{x} + \frac{1/s_0^2}{n/\sigma_0^2 + 1/s_0^2} +$$ + +$$ +posterior_{mean} = \frac{n}{n + \sigma_0^2/s_0^2}\bar{x} + \frac{\sigma_0^2/s_0^2}{n + \sigma_0^2/s_0^2} +$$ + +Thus we see, that the posterior mean is a weighted average of the prior mean and the data mean. And indeed that the effective sample size for this prior is the ratio of the variance for the data to the variance in the prior. + +This makes sense, because the larger the variance of the prior, the less information that's in it. + +The marginal distribution for Y is +$$ +N(m_0, s_0^2 + \sigma^2) +$$ + +### When $\mu$ and $\sigma^2$ is unknown + +$$ +X_i | \mu, \sigma^2 \sim N(\mu, \sigma^2) +$$ + +A prior from $\mu$ conditional on the value for $\sigma^2$ +$$ +\mu | \sigma^2 \sim N(m, \frac{\sigma^2}{w}) +$$ +$w$ is going to be the ratio of $\sigma^2$ and some variance for the Normal distribution. This is the effective sample size of the prior. + +Finally, the last step is to specify a prior for $\sigma^2$. The conjugate prior here is an inverse gamma distribution with parameters $\alpha$ and $\beta$. +$$ +\sigma^2 \sim \Gamma^{-1}(\alpha, \beta) +$$ +After many calculations... we get the posterior distribution +$$ +\sigma^2 | x \sim \Gamma^{-1}(\alpha + \frac{n}{2}, \beta + \frac{1}{2}\sum_{i = 1}^n{(x-\bar{x}^2 + \frac{nw}{2(n+2)}(\bar{x} - m)^2)}) +$$ + +$$ +\mu | \sigma^2,x \sim N(\frac{n\bar{x}+wm}{n+w}, \frac{\sigma^2}{n + w}) +$$ + +Where the posterior mean can be written as the weighted average of the prior mean and the data mean. +$$ +\frac{n\bar{x}+wm}{n+w} = \frac{w}{n + w}m + \frac{n}{n + w}\bar{x} +$$ +In some cases, we really only care about $\mu$. We want some inference on $\mu$ and we may want it such that it doesn't depend on $\sigma^2$. We can marginalize that $\sigma^2$ integrating it out. The posterior for $\mu$ marginally follows a $t$ distribution. +$$ +\mu | x \sim t +$$ +Similarly the posterior predictive distribution also is a $t$ distribution. + +Finally, note that we can extend this in various directions, this can be extended to the multivariate normal case that requires matrix vector notations and can be extended in a hierarchial fashion if we want to specify priors for $m$, $w$ and $\beta$ + +## Non Informative Priors + +We've seen examples of choosing priors that contain a significant amount of information. We've also seen some examples of choosing priors where we're attempting to not put too much information in to keep them vague. + +Another approach is referred to as objective Bayesian statistics or inference where we explicitly try to minimize the amount of information that goes into the prior. + +This is an attempt to have the data have maximum influence on the posterior + +Let's go back to coin flipping +$$ +Y_i \sim B(\theta) +$$ +How do we minimize our prior information in $\theta$? One obvious intuitive approach is to say that all values of $\theta$ are equally likely. So we could have a piror for $\theta$ which follows a uniform distribution on the interval $[0, 1]$ + +Saying all values of $\theta$ are equally likely **seems** like it would have no information in it. + +Recall however, that a $Uniform(0, 1)$ is the same as $Beta(1, 1)$ + +The effective sample size of a beta prior is the sum of its two parameters. So in this case, it has an effective sample size of 2. This is equivalent to data, with one head and one tail already in it. + +So this is not a completely non informative prior. + +We could think about a prior that has less information. For example $Beta(\frac{1}{2}, \frac{1}{2})$, this would have half as much information with an effective sample size of one. + +We can take this even further. Think about something like $Beta(0.001, 0.001)$ This would have much less information, with the effective sample size fairly close to zero. In this case, the data would determine the posterior and there would be very little influence from the prior. + +###Improper priors + +Can we go even further? We can think of the limiting case. Let's think of $Beta(0,0)$, what would that look like? +$$ +f(\theta) \propto \theta^{-1}(1-\theta)^{-1} +$$ +This is not a proper density. If you integrate this over $(0,1)$, you'll get an infinite integral, so it's not a true density in the sense of it not integrating to 1. + +There's no way to normalize it, since it has an infinite integral. This is what we refer to as an improper prior. + +It's improper in the sense that it doesn't have a proper density. But it's not necessarily imporper in the sense that we can't use it. If we collect data, we use this prior and as long as we observe one head and one tail, or **at least one success and one failure**. Then we can get a posterior +$$ +f(\theta|y) \propto \theta^{y-1}(1-\theta)^{n-y-1} \sim Beta(y, n-y) +$$ +With a posterior mean of $\frac{y}{n} =\hat{\theta}$, which you should recognize as the maximum likelihood estimate. So by using this improper prior, we get a posterior which gives us point estimates exactly the same as the frequentest approach. + +But in this case, we can also think of having a full posterior. From this, we can make interval statements, probability statements, and we can actually find an interval and say that there's 95% probability that $\theta$ is in this interval. Which is not something you can do under the frequentest approach even though we may get the same exact interval. + +### Statements about improper priors + +Improper priors are okay as long as the posterior itself is proper. There may be some mathematical things that need to be checked and you may need to have certain restrictions on the data. In this case, we needed to make sure that we observed at least one head and one tail to get a proper posterior. + +But as long as the posterior is proper, we can go forwards and do Bayesian inference even with an improper prior. + +The second point is that for many problems there does exist a prior, typically an improper prior that will lead to the same point estimates as you would get under the frequentest paradigm. So we can get very similar results, results that are fully dependent on the data, under the Bayesian approach. + +But in this case, we can also have continue to have a posterior and make posterior interval estimates and talk about posterior probabilities of the parameter. + +### Normal Case + +Another example is thinking about the normal case. +$$ +Y_i \stackrel{iid}\sim N(\mu, \sigma^2) +$$ +Let's start off by assuming that $\sigma^2$ is known and we'll just focus on the mean $\mu$. + +We can think about a vague prior like before and say that +$$ +\mu \sim N(0, 1000000^2) +$$ +This would just spread things out across the real line. That would be a fairly non informative prior covering a lot of possibilities. We can then think about taking the limit, what happens if we let the variance go to $\infty$. In that case, we're basically spreading out this distribution across the entire real number line. We can say that the density is just a constant across the whole real line. +$$ +f(\mu) \propto 1 +$$ +This is an improper prior because if you integrate the real line you get an infinite answer. However, if we go ahead and find the posterior +$$ +f(\mu|y) \propto f(y|\mu)f(\mu) \propto exp(-\frac{1}{2\sigma^2}\sum{(y_i - \mu)^2})(1) +$$ + +$$ +f(\mu | y) \propto exp(-\frac{1}{2\sigma^2/n}(\mu - \bar{y})^2) +$$ + +$$ +\mu | y \sim N(\bar{y}, \frac{\sigma^2}{n}) +$$ + +This should look just like the maximum likelihood estimate. + +### Unknown Variance + +In the case that $\sigma^2$ is unknown, the standard non informative prior is +$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$ + +$$ +\sigma^2 \sim \Gamma^{-1}(0,0) +$$ + +This is an improper prior and it's uniform on the log scale of $\sigma^2$. + +In this case, we'll end up with a posterior for $\sigma^2$ +$$ +\sigma^2|y \sim \Gamma^{-1}(\frac{n-1}{2}, \frac{1}{2}\sum{(y_i - \bar{y})^2}) +$$ +This should also look reminiscent of quantities we get as a frequentest. For example, the samples standard deviation + +## Jeffreys Prior + +Choosing a uniform prior depends upon the particular parameterization. + +Suppose I used a prior which is uniform on the log scale for $\sigma^2$ +$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$ +Suppose somebody else decides, that they just want to put a uniform prior on $\sigma^2$ itself. +$$ +f(\sigma^2) \propto 1 +$$ +These are both uniform on certain scales or certain parameterizations, but they are different priors. So when we compute the posteriors, they will be different as well. + + The key thing is that uniform priors are not invariant with respect to transformation. Depending on how you parameterize the problem, you can get different answers by using a uniform prior + +One attempt to round this out is to use Jeffrey's Prior + +Jeffrey's Prior is defined as the following +$$ +f(\theta) \propto \sqrt{\mathcal{I(\theta)}} +$$ +Where $\mathcal{I}(\theta)$ is the fisher information of $\theta$. In most cases, this will be an improper prior. + +### Normal Data + +For the example of Normal Data +$$ +Y_i \sim N(\mu, \sigma^2) +$$ + +$$ +f(\mu) \propto 1 +$$ + +$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$ + +Where $\mu$ is uniform and $\sigma^2$ is uniform on the log scale. + +This prior will then be transformation invariant. We will end up putting the same information into the prior even if we use a different parameterization for the Normal. + +### Binomial + +$$ +Y_i \sim B(\theta) +$$ + +$$ +f(\theta) \propto \theta^{-\frac{1}{2}}(1-\theta)^{-\frac{1}{2}} \sim Beta(\frac{1}{2},\frac{1}{2}) +$$ + +This is a rare example of where the Jeffreys prior turns out to be a proper prior. + +You'll note that this prior actually does have some information in it. It's equivalent to an effective sample size of one data point. However, this information will be the same, not depending on the parameterization we use. + +In this case, we have $\theta$ as a probability, but another alternative which is sometimes used is when we model things on a logistics scale. + +By using the Jeffreys prior, we'll maintain the exact same information. + +### Closing information about priors + +Other possible approaches to objective Bayesian inference includes priors such as reference priors and maximum entropy priors. + +A related concept to this is called empirical Bayesian analysis. The idea in empirical Baye's is that you use the data to help inform your prior; such as by using the mean of the data to set the mean of the prior distribution. This approach often leads to reasonable point estimates in your posterior. However, it's sort of cheating since you're using your data twice and as a result may lead to improper uncertainty estimates. + +## Fisher Information + +The Fisher information (for one parameter) is defined as +$$ +\mathcal{I}(\theta) = E[(\frac{d}{d\theta}log{(f(X|\theta))})^2] +$$ +Where the expectation is taken with respect to $X$ which has PDF $f(x|\theta)$. This quantity is useful in obtaining estimators for $\theta$ with good properties, such as low variance. It is also the basis for Jeffreys prior. + +**Example:** Let $X | \theta \sim N(\theta, 1)$. Then we have +$$ +f(x|\theta) = \frac{1}{\sqrt{2\pi}}exp[-\frac{1}{2}(x-\theta)^2] +$$ + +$$ +\log{(f(x|\theta))} = -\frac{1}{2}\log{(2\pi)}-\frac{1}{2}(x-\theta)^2 +$$ + +$$ +(\frac{d}{d\theta}log{(f(x|\theta))})^2 = (x-\theta)^2 +$$ + +and so $\mathcal{I}(\theta) = E[(X - \theta)^2] = Var(X) = 1$ + +## Linear Regression + +###Brief Review of Regression + +Recall that linear regression is a model for predicting a response or dependent variable ($Y$, also called an output) from one or more covariates or independent variables ($X$, also called explanatory variables, inputs, or features). For a given value of a single $x$, the expected value of $y$ is +$$ +E[y] = \beta_0 + \beta_1x +$$ +or we could say that $Y \sim N(\beta_0 + \beta_1x, \sigma^2)$. For data $(x_1, y_1), \dots , (x_n, y_n)$, the fitted values for the coefficients, $\hat{\beta_0}$ and $\hat{\beta_1}$ are those that minimize the sum of squared errors $\sum_{i = 1}^n{(y_i - \hat{y_i})^2}$, where the predicted values for the response are $\hat{y} = \hat{\beta_0} + \hat{\beta_1}x$. We can get these values from R. These fitted coefficients give the least-squares line for the data. + +This model extends to multiple covariates, with one $\beta_j$ for each $k$ covariates +$$ +E[y_i] = \beta_0 + \beta_1x_{i1} + \dots + \beta_kx_{ik} +$$ +Optionally, we can represent the multivariate case using vector-matrix notation. + +### Conjugate Modeling + +In the Bayesian framework, we treat the $\beta$ parameters as unknown, put a prior on them, and then find the posterior. We might treat $\sigma^2$ as fixed and known, or we might treat it as an unknown and also put a prior on it. Because the underlying assumption of a regression model is that the errors are independent and identically normally distributed with mean $0$ and variance $\sigma^2$, this defines a normal likelihood. + +#### $\sigma^2$ known + +Sometimes we may know the value of the error variance $\sigma^2$. This simplifies calculations. The conjugate prior for the $\beta$'s is a normal prior. In practice, people typically use a non-informative prior, i.e., the limit as the variance of the normal prior goes to infinity, which has the same mean as the standard least-squares estimates. If we are only estimating $\beta$ and treating $\sigma^2$ as known, then the posterior for $\beta$ is a (multivariate) normal distribution. If we just have a single covariate, then the posterior for the slope is +$$ +\beta_1 | y \sim N(\frac{\sum_{i = 1}^n{(x_i-\bar{x})(y_i - \bar{y})}}{\sum_{i=1}^n{(x_i-\bar{x})^2}}, \frac{\sigma^2}{\sum_{i=1}^n{(x_i - \bar{x})^2}}) +$$ +If we have multiple covariates, then using a matrix-vector notation, the posterior for the vector of coefficients is +$$ +\beta | y \sim N((X^tX)^{-1}X^ty, (X^tX)^{-1}\sigma^2) +$$ +where $X$ denotes the design matrix and $X^t$ is the transpose of $X$. The intercept is typically included in $X$ as a column of $1$'s. Using an improper prior requires us to have at least as many data points as we have parameters to ensure that the posterior is proper. + +#### $\sigma^2$ Unknown + +If we treat both $\beta$ and $\sigma^2$ as unknown, the standard prior is the non-informative Jeffreys prior, $f(\beta, \sigma^2) \propto \frac{1}{\sigma^2}$. Again, the posterior mean for $\beta$ will be the same as the standard least-squares estimates. The posterior for $\beta$ conditional on $\sigma^2$ is the same normal distributions as when $\sigma^2$ is known, but the marginal posterior distribution for $\beta$, with $\sigma^2$ integrated out is a $t$ distribution, analogous to the $t$ tests for significance in standard linear regression. The posterior $t$ distribution has mean $(X^tX)^{-1}X^ty$ and scale matrix (related to the variance matrix) $s^2(X^tX)^{-1}$, where $s^2 = \sum_{i = 1}^n{(y_i - \hat{y_i})^2/(n - k - 1)}$. The posterior distribution for $\sigma^2$ is an inverse gamma distribution +$$ +\sigma^2 | y \sim \Gamma^{-1}(\frac{n - k - 1}{2}, \frac{n - k - 1}{2}s^2) +$$ +In the simple linear regression case (single variable), the marginal posterior for $\beta$ is a $t$ distribution with mean $\frac{\sum_{i = 1}^n{(x_i-\bar{x})(y_i - \bar{y})}}{\sum_{i=1}^n{(x_i-\bar{x})^2}}$ and scale $ \frac{s^2}{\sum_{i=1}^n{(x_i - \bar{x})^2}}$. If we are trying to predict a new observation at a specified input $x^*$, that predicted value has a marginal posterior predictive distribution that is a $t$ distribution, with mean $\hat{y} = \hat{\beta_0} + \hat{\beta_1}x^*$ and scale $se_r\sqrt{1 + \frac{1}{n} + \frac{(x^* - \bar{x})^2}{(n - 1)s_x^2}}$. $se_r$ is the residual standard error of the regression, which can be found easily in R. $s_x^2$ is the sample variance of $x$. Recall that the predictive distribution for a new observation has more variability than the posterior distribution for $\hat{y}$ , because individual observations are more variable than the mean. + +## Linear Regression + +### Single Variable Regression + +We'll be looking at the Challenger dataset. It contains 23 past launches where it has the temperature at the day of launch and the O-ring damage index + +http://www.randomservices.org/random/data/Challenger2.txt +Read in the data + +```R +oring=read.table("http://www.randomservices.org/random/data/Challenger2.txt", + header=T) +# Note that attaching this masks T which is originally TRUE +attach(oring) +``` + +Now we'll see the plot + +```R +plot(T, I) +``` + +![Challenger](files/courses/BayesianStatistics/Challenger.png) + +Fit a linear model + +```R +oring.lm=lm(I~T) +summary(oring.lm) +``` + +Output of the summary + +``` +Call: +lm(formula = I ~ T) + +Residuals: + Min 1Q Median 3Q Max +-2.3025 -1.4507 -0.4928 0.7397 5.5337 + +Coefficients: + Estimate Std. Error t value Pr(>|t|) +(Intercept) 18.36508 4.43859 4.138 0.000468 +T -0.24337 0.06349 -3.833 0.000968 + +(Intercept) *** +T *** +--- +Signif. codes: +0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 + +Residual standard error: 2.102 on 21 degrees of freedom +Multiple R-squared: 0.4116, Adjusted R-squared: 0.3836 +F-statistic: 14.69 on 1 and 21 DF, p-value: 0.0009677 +``` + +Add the fitted line into the scatterplot + +```R +lines(T,fitted(oring.lm)) +``` + +![challengerfitted](files/courses/BayesianStatistics/challengerfitted.png) + +Create a 95% posterior interval for the slope + +```R +-0.24337 - 0.06349*qt(.975,21) +# [1] -0.3754047 +-0.24337 + 0.06349*qt(.975,21) +# [1] -0.1113353 +``` + +**Note:** These are the same as the frequentest confidence intervals + +If the challenger launch was at 31 degrees Fahrenheit, how much O-Ring damage would we predict? + +```R +coef(oring.lm)[1] + coef(oring.lm)[2]*31 +# [1] 10.82052 +``` + +Let's make our posterior prediction interval + +```R +predict(oring.lm,data.frame(T=31),interval="predict") +``` + +Output of `predict` + +``` + fit lwr upr +1 10.82052 4.048269 17.59276 +``` + +We can calculate the lower bound through the following formula + +```R +10.82052-2.102*qt(.975,21)*sqrt(1+1/23+((31-mean(T))^2/22/var(T))) +``` + +What's the posterior probability that the damage index is greater than zero? + +```R +1-pt((0-10.82052)/(2.102*sqrt(1+1/23+((31-mean(T))^2/22/var(T)))),21) +``` + +### Multivariate Regression + +We're looking at Galton's seminal data predicting the height of children from the height of the parents + +http://www.randomservices.org/random/data/Galton.txt +Read in the data + +```R +heights=read.table("http://www.randomservices.org/random/data/Galton.txt", + header=T) +attach(heights) +``` + +What are the columns in the dataset? + +```R +names(heights) +# [1] "Family" "Father" "Mother" "Gender" "Height" "Kids" +``` + +Let's look at the relationship between the different variables + +```R +pairs(heights) +``` + +![heightpairs](files/courses/BayesianStatistics/heightpairs.png) + +First let's start by creating a linear model taking all of the columns into account + +```R +summary(lm(Height~Father+Mother+Gender+Kids)) +``` + +Output of `summary` + +``` +Call: +lm(formula = Height ~ Father + Mother + Gender + Kids) + +Residuals: + Min 1Q Median 3Q Max +-9.4748 -1.4500 0.0889 1.4716 9.1656 + +Coefficients: + Estimate Std. Error t value Pr(>|t|) +(Intercept) 16.18771 2.79387 5.794 9.52e-09 +Father 0.39831 0.02957 13.472 < 2e-16 +Mother 0.32096 0.03126 10.269 < 2e-16 +GenderM 5.20995 0.14422 36.125 < 2e-16 +Kids -0.04382 0.02718 -1.612 0.107 + +(Intercept) *** +Father *** +Mother *** +GenderM *** +Kids +--- +Signif. codes: +0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 + +Residual standard error: 2.152 on 893 degrees of freedom +Multiple R-squared: 0.6407, Adjusted R-squared: 0.6391 +F-statistic: 398.1 on 4 and 893 DF, p-value: < 2.2e-16 +``` + +As you can see here, the `Kids` column is not significant. Let's look at a model with it removed. + +```R +summary(lm(Height~Father+Mother+Gender)) +``` + +Output of `summary` + +``` +Call: +lm(formula = Height ~ Father + Mother + Gender) + +Residuals: + Min 1Q Median 3Q Max +-9.523 -1.440 0.117 1.473 9.114 + +Coefficients: + Estimate Std. Error t value Pr(>|t|) +(Intercept) 15.34476 2.74696 5.586 3.08e-08 +Father 0.40598 0.02921 13.900 < 2e-16 +Mother 0.32150 0.03128 10.277 < 2e-16 +GenderM 5.22595 0.14401 36.289 < 2e-16 + +(Intercept) *** +Father *** +Mother *** +GenderM *** +--- +Signif. codes: +0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 + +Residual standard error: 2.154 on 894 degrees of freedom +Multiple R-squared: 0.6397, Adjusted R-squared: 0.6385 +F-statistic: 529 on 3 and 894 DF, p-value: < 2.2e-16 +``` + +This model looks good, let's go ahead and save it to a variable + +```R +heights.lm=lm(Height~Father+Mother+Gender) +``` + +From this we can tell that for each extra inch of height in a father is correlated with an extra 0.4 inches extra to the height of a child. + +We can also tell that each extra inch of height in a mother is correlated with an extra 0.3 inches extra to the height of the child. + +A male child is on average 5.2 inches taller than a female child. + +Let's create a 95% posterior interval for the difference in height by gender + +```R +5.226 - 0.144*qt(.975,894) +# [1] 4.943383 +5.226 + 0.144*qt(.975,894) +# [1] 5.508617 +``` + +Let's make a posterior prediction interval for a male and female with a father whose 68 inches and a mother whose 64 inches. + +```R +predict(heights.lm,data.frame(Father=68,Mother=64,Gender="M"), + interval="predict") + +# fit lwr upr +# 1 68.75291 64.51971 72.9861 +``` + +```R +predict(heights.lm,data.frame(Father=68,Mother=64,Gender="F"), + interval="predict") + +# fit lwr upr +# 1 63.52695 59.29329 67.76062 +``` + + + +## What's next? + +This concludes this course, if you want to go further with Bayesian statistics, the next topics to explore would be hierarchal modeling and fitting of non conjugate models with Markov Chain Monte Carlo or MCMC. diff --git a/content/notes/quadraticcongruences.md b/content/notes/quadraticcongruences.md new file mode 100644 index 0000000..594faea --- /dev/null +++ b/content/notes/quadraticcongruences.md @@ -0,0 +1,82 @@ +# Handy Quadratic Congruences Facts + +## Number of Solutions + +For congruences mod 2 + +**Proposition 16.1**. Let $f(x) = ax^2 + bx + c$ with $a$ odd, and let $\Delta = b^2 - 4ac$ be the discriminant of $f(x)$. Then, + +1. If $\Delta \equiv 1$ (mod $8$), so that $b$ is odd and $c$ is even, then $f(x) \equiv 0$ (mod $2$) has **two** solutions +2. If $\Delta \equiv 5$ (mod $8$), so that $b$ and $c$ are odd, then $f(x) \equiv 0$ (mod $2$) has **no** solutions +3. If $4 | \Delta$ , so that $b$ is even, then $f(x) \equiv 0$ (mod $2$) has exactly **one** solution. + +**Proposition 16.2.** Let $p$ be an odd prime and let $a$ be an integer. Then, + +1. If $p$ does not divide $a$, then the congruence $x^2 \equiv a$ (mod $p$) has either two solutions or no solutions. +2. If $p$ divides $a$, then $x^2 \equiv a$ (mod $p$) has exactly one solution, namely $x = 0$. + +**Legendre symbol definition**. Let $p$ be an odd prime and $a$ any integer. Then the *Legendre symbol*, written as $(\frac{a}{p})$ is defined as +$$ +(\frac{a}{p}) = \begin{cases} +1, & \text{if $x^2 \equiv a$ (mod $p$) has exactly two solutions,} \\ +0, & \text{if $x^2 \equiv a$ (mod $p$) has exactly one solution,} \\ +-1, & \text{if $x^2 \equiv a$ (mod $p$) has no soultions.} +\end{cases} +$$ +**Properties of Legendre symbol**. + +- $(\frac{a}{p}) = 0 \iff p$ divides $a$ + +- $(\frac{1}{p}) = 1$ for every odd prime $p$ + +- $a \equiv b$ (mod $p$) $\implies$ $(\frac{a}{p}) = (\frac{b}{p})$ + +- $(\frac{ab}{p}) = (\frac{a}{p})(\frac{b}{p})$ + +- If $p$ is an odd prime then, + + - $$ + (\frac{-1}{p}) = + \begin{cases} + 1, & \text{if $p \equiv 1$ (mod $4$)} \\ + -1, & \text{ if $p \equiv 3$ (mod $4$)} + \end{cases} + $$ + +- If $p$ is an odd prime then, + + - $$ + (\frac{2}{p}) = + \begin{cases} + 1, & \text{if $p \equiv 1$ (mod $8$) or $p \equiv 7$ (mod $8$)} \\ + -1, & \text{ if $p \equiv 3$ (mod $8$) or $p \equiv 5$ (mod $8$)} + \end{cases} + $$ + +- **Quadratic Reciprocity Theorem**. Let $p$ and $q$ be distinct odd primes. Then, + + - $$ + (\frac{q}{p}) = + \begin{cases} + (\frac{p}{q}), & \text{if $p \equiv 1$ (mod $4$) or $q \equiv 1$ (mod $4$)} \\ + -(\frac{p}{q}), & \text{ if $p \equiv 3$ (mod $4$) and $q \equiv 3$ (mod $4$)} + \end{cases} + $$ + +## Procedure + +When $p$ is an odd prime, a quadratic congruence $ax^2 + bx + c \equiv 0$ (mod $p$) can be transformed into a specialized form by completing the square. +\begin{align*} +ax^2 + bx + c \equiv 0 \text{ (mod $p$)} &\iff 4a(ax^2 + bx + c) \equiv 0 \text{ (mod $p$)} \\\\ +&\iff 4a^2x^2 + 4abx + 4ac \equiv 0 \text{ (mod $p$)} \\\\ +&\iff 4a^2x^2 + 4abx + 4ac + (b^2 - 4ac) \equiv b^2 - 4ac \text{ (mod $p$)} \\\\ +&\iff 4a^2x^2 + 4abx + b^2 \equiv b^2 - 4ac \text{ (mod $p$)} \\\\ +&\iff (2ax+b)^2 \equiv b^2 - 4ac \text{ (mod $p$)} +\end{align*} + +## Quadratic Congruences Modulo a prime power + +Let $a$ be the solution to $f(x) \equiv 0$ (mod $p$) where $p$ is an odd prime. Consider $b = pt + a$. Then, $f(b) \equiv 0$ (mod $p^2$) if $f^\prime(a)t \equiv -\frac{f(a)}{p}$ (mod $p$). + +In general, let $a$ be the solution to $f(x) \equiv 0$ (mod $p^n$) where $p$ is an odd prime. Consider $b = pt + a$. Then, $f(b) \equiv 0$ (mod $p^{n + 1}$) if $f^\prime(a)t \equiv -\frac{f(a)}{p^n}$ (mod $p$) + diff --git a/content/notes/realanalysis.md b/content/notes/realanalysis.md new file mode 100644 index 0000000..af1c1f5 --- /dev/null +++ b/content/notes/realanalysis.md @@ -0,0 +1,93 @@ +# Real Analysis Sheet + +**Fact:** $\forall a,b, \in \mathbb{R}$, $\sqrt{ab} \le \frac{1}{2}(a + b)$. + +**Bernoulli's Inequality:** If $x > -1$, then $(1 + x)^n \ge 1 + nx$, $\forall n \in \mathbb{N}$. + +**Triangle Inequality:** If $a,b \in \mathbb{R}$, then $|a + b| \le |a| + |b|$. + +**Epsilon Neighborhood Definition:** + +Let $a \in \mathbb{R}$ and $\epsilon > 0$. The $\epsilon$-neighborhood of $a$ is the set $V_\epsilon(a) = \{ x \in \mathbb{R}, |x - a| < \epsilon\}$. + +**Archimedean Property:** If $x \in \mathbb{R}$, then $\exists n_x \in \mathbb{N}$ such that $x \le n_x$. + +**Convergence Definition:** + +$X = (x_n)$ converges to $x \in \mathbb{R}$ if $\forall \epsilon > 0, \exists k \in \mathbb{N}$ such that $\forall n \ge k, |x_n - x| < \epsilon$. + +**Fact:** A sequence in $\mathbb{R}$ can have at most one limit. + +**Theorem 3.1.9:** + +If $(a_n)$ is a sequence in $\mathbb{R}$ such that $a_n \rightarrow 0$, and for some constant $c > 0, m \in \mathbb{N}$, + +$|x_n - x| \le ca_n, \forall n \ge m$, then $x_n \rightarrow x$. + +**Theorem 3.2.7:** + +(a) If $x_n \rightarrow x$, then $|x_n| \rightarrow |x|$. + +(b) If $x_n \rightarrow x$ and $x_n \ge 0$, then $\sqrt{x_n} \rightarrow \sqrt{x}$. + +**Ratio Test:** + +Let $\{x_n\} \subseteq \mathbb{R}^+$ such that $L = \lim{(\frac{x_{n + 1}}{x_n})}$. If $L < 1$, then $x_n \rightarrow 0$. + +**Theorem 3.2.2:** Every convergent sequence is bounded. (The converse is not necessarily true) + +**Squeeze Theorem:** + +If $x_n \rightarrow x, y_n \rightarrow y,$ and $z_n \rightarrow x$ such that $x_n \le y_n \le z_n, \forall n \in \mathbb{N}$ then $y = x$. + +**Monotone Convergence Theorem** + +Let $X = (x_n)$ be a subsequence in $\mathbb{R}$. + +(a) If $X$ is monotonically increasing and bounded above then $\lim{x_n} = sup\{x_n : n \in \mathbb{N}\}$ + +(b) If $X$ is monotonically decreasing and bounded below then $\lim{x_n} = inf\{x_n : n \in \mathbb{N}\}$ + +**Useful Fact:** If $\lim{x_n} = a \in \mathbb{R}$, then $\lim{x_{n + 1}} = a$. + +**Interesting Application of MCT:** + +Let $s_1 > 0$ be arbitrary, and define $s_{n + 1} = \frac{1}{2}(s_n + \frac{a}{s_n})$. We know $s_n \rightarrow \sqrt{a}$. + +**Euler's Number:** Consider the sequence $e_n = (1 + \frac{1}{n})^n$. We know $e_n \rightarrow e$. + +**Theorem 3.4.2:** If $X = (x_n) \subseteq \mathbb{R}$ converges to $x$, then every subsequence converges to $x$. + +**Corollary:** If $X = (x_n) \subseteq \mathbb{R}$ has a subsequence that diverges then $X$ diverges. + +**Monotone Sequence Theorem**: If $X = (x_n) \subseteq \mathbb{R}$, then it contains a monotone subsequence. + +**Bolzano-Weierstrass Theorem:** Every bounded sequence in $\mathbb{R}$ has a convergent subsequence. + +**Theorem 3.4.12:** A bounded $(x_n) \in \mathbb{R}$ is convergent iff $liminf(x_n) = limsup(x_n)$. + +**Cauchy Criteria for Convergence:** Let $X = (x_n) \subseteq \mathbb{R}$. We say that $X$ is cauchy if $\forall \epsilon > 0, \exists N \in \mathbb{N}$ such that $\forall n,m \ge N, |x_n - x_m| < \epsilon$. We know that a sequence converges iff it is cauchy. + +**P-Series:** Series of the form $s_n = \sum_{i = 0}^n{\frac{1}{n^p}}$ is convergent for $p > 1$. + +**Geometric Series:** + +Series of the form $s_n = \sum_{i = 0}^n{ar^i}$ has the following partial sum $a\frac{1 - r^n}{1 - r}$ and converges to $\frac{a}{1 - r}$ if $|r| < 1$. + +**Comparison Test:** + +Let $(x_n), (y_n) \subseteq \mathbb{R}$. Suppose that for some $k \in \mathbb{N}, 0 \le x_n \le y_n,$ for $n \ge k$. + +(a) If $\sum{y_n} < \infty$, then $\sum{x_n} < \infty$. + +(b) If $\sum{x_n} = \infty$, then $\sum{y_n} = \infty$. + +**Limit Comparison Test:** + +Let $(x_n), (y_n)$ be strictly positive sequence of real numbers. Suppose $r = \lim{\frac{x_n}{y_n}}$. + +(a) If $r \ne 0$, then $\sum{x_n} < \infty \iff \sum{y_n} < \infty$. + +(b) If ($r = 0$ and $\sum{y_n} < \infty$), then $\sum{x_n} < \infty$. + + \ No newline at end of file diff --git a/content/notes/reproducibleresearch.md b/content/notes/reproducibleresearch.md new file mode 100644 index 0000000..77e1ea2 --- /dev/null +++ b/content/notes/reproducibleresearch.md @@ -0,0 +1,20 @@ +--- +title: Reproducible Research +showthedate: false +--- + + + +# Reproducible Research + +In the Winter of 2017, I took a coursera course on Reproducible Research taught by Dr. Peng from John Hopkins University + +Below are my notes for each of the four weeks. + +[Week 1](week1) + +[Week 2](week2) + +[Week 3](week3) + +[Week 4](week4) diff --git a/content/notes/reproducibleresearch/week1.md b/content/notes/reproducibleresearch/week1.md new file mode 100644 index 0000000..4db0cc4 --- /dev/null +++ b/content/notes/reproducibleresearch/week1.md @@ -0,0 +1,397 @@ +# Reproducible Research Week 1 + +## Replication + +The ultimate standard for strengthening scientific evidence is replication of finding and conducting studies with independent + +- Investigators +- Data +- Analytical Methods +- Laboratories +- Instruments + +Replication is particularly important in studies that can impact broad policy or regulatory decisions + + + +### What's wrong with replication? + +Some studies cannot be replicated + +- No time, opportunistic +- No money +- Unique + +*Reproducible Research:* Make analytic data and code available so that others may reproduce findings + + + +Reproducibility bridges the gap between replication which is awesome and doing nothing. + + + +## Why do we need reproducible research? + +New technologies increasing data collection throughput; data are more complex and extremely high dimensional + +Existing databases can be merged into new "megadatabases" + +Computing power is greatly increased, allowing more sophisticated analyses + +For every field "X" there is a field "Computational X" + + + +## Research Pipeline + +Measured Data -> Analytic Data -> Computational Results -> Figures/Tables/Numeric Summaries -> Articles -> Text + +Data/Metadata used to develop test should be made publically available + +The computer code and fully specified computational procedures used for development of the candidate omics-based test should be made sustainably available + +"Ideally, the computer code that is released will encompass all of the steps of computational analysis, including all data preprocessing steps. All aspects of the analysis needs to be transparently reported" -- IOM Report + + + +### What do we need for reproducible research? + +- Analytic data are available +- Analytic code are available +- Documentation of code and data +- Standard means of distribution + + + +### Who is the audience for reproducible research? + +Authors: + +- Want to make their research reproducible +- Want tools for reproducible research to make their lives easier (or at least not much harder) + +Readers: + +- Want to reproduce (and perhaps expand upon) interesting findings +- Want tools for reproducible research to make their lives easier. + +### Challenges for reproducible research + +- Authors must undertake considerable effort to put data/results on the web (may not have resources like a web server) +- Readers must download data/results individually and piece together which data go with which code sections, etc. +- Readers may not have the same resources as authors +- Few tools to help authors/readers + +### What happens in reality + +Authors: + +- Just put stuff on the web +- (Infamous for disorganization) Journal supplementary materials +- There are some central databases for various fields (e.g biology, ICPSR) + +Readers: + +- Just download the data and (try to) figure it out +- Piece together the software and run it + +## Literate (Statistical) Programming + +An article is a stream of text and code + +Analysis code is divided into text and code "chunks" + +Each code chunk loads data and computes results + +Presentation code formats results (tables, figures, etc.) + +Article text explains what is going on + +Literate programs can be weaved to produce human-readable documents and tagled to produce machine-readable documents + +Literate programming is a general concept that requires + +1. A documentation language (human readable) +2. A programming language (machine readable) + +Knitr is an R package that brings a variety of documentation languages such as Latex, Markdown, and HTML + +### Quick summary so far + +Reproducible research is important as a minimum standard, particularly for studies that are difficult to replicate + +Infrastructure is needed for creating and distributing reproducible document, beyond what is currently available + +There is a growing number of tools for creating reproducible documents + + + +**Golden Rule of Reproducibility: Script Everything** + +## Steps in a Data Analysis + +1. Define the question +2. Define the ideal data set +3. Determine what data you can access +4. Obtain the data +5. Clean the data +6. Exploratory data analysis +7. Statistical prediction/modeling +8. Interpret results +9. Challenge results +10. Synthesize/write up results +11. Create reproducible code + +"Ask yourselves, what problem have you solved, ever, that was worth solving, where you knew all of the given information in advance? Where you didn't have a surplus of information and have to filter it out, or you had insufficient information and have to go find some?" -- Dan Myer + +Defining a question is the kind of most powerful dimension reduction tool you can ever employ. + +### An Example for #1 + +**Start with a general question** + +Can I automatically detect emails that are SPAM or not? + +**Make it concrete** + +Can I use quantitative characteristics of emails to classify them as SPAM? + +### Define the ideal data set + +The data set may depend on your goal + +- Descriptive goal -- a whole population +- Exploratory goal -- a random sample with many variables measured +- Inferential goal -- The right population, randomly sampled +- Predictive goal -- a training and test data set from the same population +- Causal goal -- data from a randomized study +- Mechanistic goal -- data about all components of the system + +### Determine what data you can access + +Sometimes you can find data free on the web + +Other times you may need to buy the data + +Be sure to respect the terms of use + +If the data don't exist, you may need to generate it yourself. + +### Obtain the data + +Try to obtain the raw data + +Be sure to reference the source + +Polite emails go a long way + +If you load the data from an Internet source, record the URL and time accessed + +### Clean the data + +Raw data often needs to be processed + +If it is pre-processed, make sure you understand how + +Understand the source of the data (census, sample, convenience sample, etc) + +May need reformatting, subsampling -- record these steps + +**Determine if the data are good enough** -- If not, quit or change data + +### Exploratory Data Analysis + +Look at summaries of the data + +Check for missing data + +-> Why is there missing data? + +Look for outliers + +Create exploratory plots + +Perform exploratory analyses such as clustering + +If it's hard to see your plots since it's all bunched up, consider taking the log base 10 of an axis + +`plot(log10(trainSpan$capitalAve + 1) ~ trainSpam$type)` + +### Statistical prediction/modeling + +Should be informed by the results of your exploratory analysis + +Exact methods depend on the question of interest + +Transformations/processing should be accounted for when necessary + +Measures of uncertainty should be reported. + +### Interpret Results + +Use the appropriate language + +- Describes +- Correlates with/associated with +- Leads to/Causes +- Predicts + +Gives an explanation + +Interpret Coefficients + +Interpret measures of uncertainty + +### Challenge Results + +Challenge all steps: + +- Question +- Data Source +- Processing +- Analysis +- Conclusions + +Challenge measures of uncertainty + +Challenge choices of terms to include in models + +Think of potential alternative analyses + +### Synthesize/Write-up Results + +Lead with the question + +Summarize the analyses into the story + +Don't include every analysis, include it + +- If it is needed for the story +- If it is needed to address a challenge +- Order analyses according to the story, rather than chronologically +- Include "pretty" figures that contribute to the story + +### In the lecture example... + +Lead with the question + +​ Can I use quantitative characteristics of the emails to classify them as SPAM? + +Describe the approach + +​ Collected data from UCI -> created training/test sets + +​ Explored Relationships + +​ Choose logistic model on training set by cross validation + +​ Applied to test, 78% test set accuracy + +Interpret results + +​ Number of dollar signs seem reasonable, e.g. "Make more money with Viagra $ $ $ $" + +Challenge Results + +​ 78% isn't that great + +​ Could use more variables + +​ Why use logistic regression? + + + +## Data Analysis Files + +Data + +- Raw Data +- Processed Data + +Figures + +- Exploratory Figures +- Final Figures + +R Code + +- Raw/Unused Scripts +- Final Scripts +- R Markdown Files + +Text + +- README files +- Text of Analysis/Report + +### Raw Data + +Should be stored in the analysis folder + +If accessed from the web, include URL, description, and date accessed in README + +### Processed Data + +Processed data should be named so it is easy to see which script generated the data + +The processing script -- processed data mapping should occur in the README + +Processed data should be tidy + +### Exploratory Figures + +Figures made during the course of your analysis, not necessarily part of your final report + +They do not need to be "pretty" + +### Final Figures + +Usually a small subset of the original figures + +Axes/Colors set to make the figure clear + +Possibly multiple panels + +### Raw Scripts + +May be less commented (but comments help you!) + +May be multiple versions + +May include analyses that are later discarded + +### Final Scripts + +Clearly commented + +- Small comments liberally - what, when, why, how + +- Bigger commented blocks for whole sections + +Include processing details + +Only analyses that appear in the final write-up + +### R Markdown Files + +R Markdown files can be used to generate reproducible reports + +Text and R code are integrated + +Very easy to create in RStudio + +### Readme Files + +Not necessary if you use R Markdown + +Should contain step-by-step instructions for analysis + +### Text of the document + +It should contain a title, introduction (motivation), methods (statistics you used), results (including measures of uncertainty), and conclusions (including potential problems) + +It should tell a story + +It should not include every analysis you performed + +References should be included for statistical methods \ No newline at end of file diff --git a/content/notes/reproducibleresearch/week2.md b/content/notes/reproducibleresearch/week2.md new file mode 100644 index 0000000..49779f6 --- /dev/null +++ b/content/notes/reproducibleresearch/week2.md @@ -0,0 +1,227 @@ +## Coding Standards for R + +1. Always use text files/text editor +2. Indent your code +3. Limit the width of your code (80 columns?) +4. Author suggests indentation of 4 spaces at minimum +5. Limit the length of individual functions + +## What is Markdown? + +Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it structurally to valid XHTML/HTML + +## Markdown Syntax + +`*This text will appear italicized!*` + +*This text will appear italicized!* + +`**This text will appear bold!**` + +**This text will appear bold** + +`## This is a secondary heading` + +`###This is a tertiary heading ` + +## This is a secondary heading + +### This is a tertiary heading + +Unordered Lists + +`- first item in list` + +`- second item in list` + +- first item in list +- second item in list + +Ordered lists + +`1. first item in list` + +`2. second item in list` + +`3. third item in list` + +1. first item in list +2. second item in list +3. third item in list + +Create links + +`[Download R](http://www.r-project.org/)` + +[Download R](http://www.r-project.org/) + +Advanced linking + +`I spent so much time reading [R bloggers][1] and [Simply Statistics][2]!` + +`[1]: http://www.r-bloggers.com/ "R bloggers"` + +`[2]: http://simplystatistics.org/ "Simply Statistics"` + +I spent so much time reading [R bloggers][1] and [Simply Statistics][2]! + +[1]: http://www.r-bloggers.com/ "R bloggers" + +[2]: http://simplystatistics.org/ "Simply Statistics" + +Newlines require a double space after the end of a line + +## What is Markdown? + +Created by John Gruber and Aaron Swartz. It is a simplified version of "markup" languages. It allows one to focus on writing as opposed to formatting. Markdown provides a simple, minimal, and intuitive way of formatting elements. + +You can easily convert Markdown to valid HTML (and other formats) using existing tools. + +## What is R Markdown? + +R Markdown is the integration of R code with markdown. It allows one to create documents containing "live" R code. R code is evaluated as part of the processing of the markdown and its results are inserted into the Markdown document. R Markdown is a core tool in **literate statistical programming** + +R Markdown can be converted to standard markdown using `knitr` package in R. Markdown can then be converted to HTML using the `markdown` package in R. This workflow can be easily managed using R Studio. One can create powerpoint like slides using the `slidify` package. + +## Problems, Problems + +- Authors must undertake considerable effort to put data/results on the web +- Readers must download data/results individually and piece together which data go with which code sections, etc. +- Authors/readers must manually interact with websites +- There is no single documents to integrate data analysis with textual representations; i.e data, code, and text are not linked + +One of the ways to resolve this is to simply put the data and code together in the same document so that people can execute the code in the right order, and the data are read at the right times. You can have a single document that integrates the data analysis with all the textual representations. + +## Literate Statistical Programming + +- Original idea comes from Don Knuth +- An article is a stream of **text** and **code** +- Analysis code is divded into text and code "chunks" +- Presentation code formats results (tables, figures, etc.) +- Article text explains what is going on +- Literate programs are weaved to produce human-readable documents and tangled to produce machine-readable documents. + +## Literate Statistical Programming + +- Literate programming is a general concept. We need + - A documentation language + - A programming language +- `knitr` supports a variety of documentation languages + +## How Do I Make My Work Reproducible? + +- Decide to do it (ideally from the start) +- Keep track of everything, hopefully through a version control system +- Use software in which operations can be coded +- Don't save output +- Save data in non-proprietary formats + +## Literate Programming: Pros + +- Text and code all in one place, logical order +- Data, results automatically updated to reflect external changes +- Code is live -- automatic "regression test" when building a document + +## Literate Programming: Cons + +- Text and code are all in one place; can make documents difficult to read, especially if there is a lot of code +- Can substantially slow down processing of documents (although there are tools to help) + +## What is Knitr Good For? + +- Manuals +- Short/Medium-Length technical documents +- Tutorials +- Reports (Especially if generated periodically) +- Data Preprocessing documents/summaries + +## What is knitr NOT good for? + +- Very long research articles +- Complex time-consuming computations +- Documents that require precise formatting + +## Non-GUI Way of Creating R Markdown documents + +```R +library(knitr) +setwd() +knit2html('document.Rmd') +browseURL('document.html') +``` + +## A few notes about knitr + +- knitr will fill a new document with filler text; delete it + +- Code chunks begin with ` ```{r}` and ends with ` ``` ` + +- All R code goes in between these markers + +- Code chunks can have names, which is useful when we start making graphics + + ` ```{r firstchunk}` + + `## R code goes here` + + ` ``` ` + +- By default, code in a code chunk is echoed, as will the results of the computation (if there are results to print) + +## Processing of knitr documents + +- You write RMarkdown document (.Rmd) +- knitr produces a Markdown document (.md) +- knitr converts the Markdown document into HTML (by default) +- .Rmd -> .md -> .html +- You should NOT edit (or save) the .md or .html documents until you are finished + +## Inline Text Computations + +You can reference variable in RMarkdown through the following + +``` +`The current time is `r time`. My favorite random number is `r rand` +``` + +## Setting Global Options + +- Sometimes we want to set options for every code chunk that are different from the defaults +- For example, we may want to suppress all code echoing and results output +- We have to write some code to set these global options + +Example for suppressing all code chunks + +```R +​```{r setoptions, echo=FALSE} +opts_chunk$set(echo=False, results = "hide") +​``` +``` + +## Some Common Options + +- Output + - Results: "axis", "hide" + - echo: TRUE, FALSE +- Figures + - fig.height: numeric + - fig.width: numeric + +## Caching Computations + +- What if one chunk takes a long time to run? +- All chunks have to be re-computed every time you re-knit the file +- The `cache=TRUE` option can be set on a chunk-by-chunk basis to store results of computation +- After the first run, results are loaded from cache + +## Caching Caveats + +- If the data or code (or anything external) changes, you need to re-run the cache code chunks +- Dependencies are not checked explicitly!!!! +- Chunks with significant *side effects* may not be cacheable + +## Summary of knitr + +- Literate statistical programming can be a useful way to put text, code, data, output all in one document +- knitr is a powerful tool for iterating code and text in a simple document format + diff --git a/content/notes/reproducibleresearch/week3.md b/content/notes/reproducibleresearch/week3.md new file mode 100644 index 0000000..1a92f30 --- /dev/null +++ b/content/notes/reproducibleresearch/week3.md @@ -0,0 +1,308 @@ +## tl;dr + +People are busy, especially managers and leaders. Results of data analyses are sometimes presented in oral form, but often the first cut is presented via email. + +It is often useful therefore, to breakdown the results of an analysis into different levels of granularity/detail + +## Hierarchy of Information: Research Paper + +- Title / Author List + - Speaks about what the paper is about + - Hopefully interesting + - No detail +- Abstract + - Motivation of the problem + - Bottom Line Results +- Body / Results + - Methods + - More detailed results + - Sensitivity Analysis + - Implication of Results +- Supplementary Materials / Gory Details + - Details on what was done +- Code / Data / Really Gory Details + - For reproducibility + + + +## Hierarchy of Information: Email Presentation + +- Subject Line / Subject Info + - At a minimum: include one + - Can you summarize findings in one sentence? +- Email Body + - A brief description of the problem / context: recall what was proposed and executed; summarize findings / results. (Total of 1-2 paragraphs) + - If action is needed to be taken as a result of this presentation, suggest some options and make them as concrete as possible + - If questions need to be addressed, try to make them yes / no +- Attachment(s) + - R Markdown file + - knitr report + - Stay Concise: Don't spit out pages of code +- Links to Supplementary Materials + - Code / Software / Data + - Github Repository / Project Website + + + +## DO: Start with Good Science + +- Remember: Garbage, in, garbage out +- Find a coherent focused question. This helps solve many problems +- Working with good collaborators reinforces good practices +- Something that's interesting to you will hopefully motivate good habits + +## DON'T: Do Things By Hand + +- Editing spreadsheets of data to "clean it up" + - Removing outliers + - QA / QC + - Validating +- Editing tables or figures (e.g rounding, formatting) +- Downloading data from a website +- Moving data around your computer, splitting, or reformatting files. + +Things done by hand need to precisely documented (this is harder than it sounds!) + +## DON'T: Point and Click + +- Many data processing / statistical analysis packages have graphical user interfaces (GUIs) +- GUIs are convenient / intuitive but the actions you take with a GUI can be difficult for others to reproduce +- Some GUIs produce a log file or script which includes equivalent commands; these can be saved for later examination +- In general, be careful with data analysis software that is highly interactive; ease of use can sometimes lead to non-reproducible analyses. +- Other interactive software, such as text editors, are usually fine. + + +## DO: Teach a Computer + +If something needs to be done as part of your analysis / investigation, try to teach your computer to do it (even if you only need to do it once) + +In order to give your computer instructions, you need to write down exactly what you mean to do and how it should be done. Teaching a computer almost guarantees reproducibility + +For example, by, hand you can + + 1. Go to the UCI Machine Learning Repository at http://archive.ics.uci.edu/mil/ + 2. Download the Bike Sharing Dataset + +Or you can teach your computer to do it using R + +```R +download.file("http://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip", "ProjectData/Bike-Sharing-Dataset.zip") +``` + +Notice here that: + +- The full URL to the dataset file is specified +- The name of the file saved to your local computer is specified +- The directory to which the filed was saved is specified ("ProjectData") +- Code can always be executed in R (as long as link is available) + +## DO: Use Some Version Control + +It helps you slow things down by adding changes into small chunks. (Don't just do one massive commit). It allows one to track / tag snapshots so that one can revert back to older versions of the project. Software like Github / Bitbucket / SourceForge make it easy to publish results. + + + +## DO: Keep Track of Your Software Environment + +If you work on a complex project involving many tools / datasets, the software and computing environment can be critical for reproducing your analysis. + +**Computer Architecture**: CPU (Intel, AMD, ARM), CPU Architecture, GPUs + +**Operating System**: Windows, Mac OS, Linux / Unix + +**Software Toolchain**: Compilers, interpreters, command shell, programming language (C, Perl, Python, etc.), database backends, data analysis software + +**Supporting software / infrastructure**: Libraries, R packages, dependencies + +**External dependencies**: Websites, data repositories, remote databases, software repositories + +**Version Numbers:** Ideally, for everything (if available) + +This function in R helps report a bunch of information relating to the software environment + +```R +sessionInfo() +``` + +## DON'T: Save Output + +Avoid saving data analysis output (tables, figures, summaries, processed data, etc.), except perhaps temporarily for efficiency purposes. + +If a stray output file cannot be easily connected with the means by which it was created, then it is not reproducible + +Save the data + code that generated the output, rather than the output itself. + +Intermediate files are okay as long as there is clear documentation of how they were created. + +## DO: Set Your Seed + +Random number generators generate pseudo-random numbers based on an initial seed (usually a number or set of numbers) + +​ In R, you can use the `set.seed()` function to set the seed and to specify the random number generator to use + +Setting the seed allows for the stream of random numbers to be exactly reproducible + +Whenever you generate random numbers for a non-trivial purpose, **always set the seed**. + +## DO: Think About the Entire Pipeline + +- Data analysis is a lengthy process; it is not just tables / figures/ reports +- Raw data -> processed data -> analysis -> report +- How you got the end is just as important as the end itself +- The more of the data analysis pipeline you can make reproducible, the better for everyone + +## Summary: Checklist + +- Are we doing good science? + - Is this interesting or worth doing? +- Was any part of this analysis done by hand? + - If so, are those parts precisely documented? + - Does the documentation match reality? +- Have we taught a computer to do as much as possible (i.e. coded)? +- Are we using a version control system? +- Have we documented our software environment? +- Have we saved any output that we cannot reconstruct from original data + code? +- How far back in the analysis pipeline can we go before our results are no longer (automatically reproducible) + + +## Replication and Reproducibility + +Replication + +- Focuses on the validity of the scientific claim +- Is this claim true? +- The ultimate standard for strengtening scientiffic evidence +- New investigators, data, analytical methods, laboratories, instruments, etc. +- Particularly important in studies that can impact broad policy or regulatory decisions. + +Reproducibility + +- Focuses on the validity of the data analysis +- Can we trust this analysis? +- Arguably a minimum standard for any scientific study +- New investigators, same data, same methods +- Important when replication is impossible + +## Background and Underlying Trends + +- Some studies cannot be replicated: No time, no money, or just plain unique / opportunistic +- Technology is increasing data collection throughput; data are more complex and high-dimensional +- Existing databases can be merged to become bigger databases (but data are used off-label) +- Computing power allows more sophisticated analyses, even on "small" data +- For every field "X", there is a "Computational X" + +## The Result? + +- Even basic analyses are difficult to describe +- Heavy computational requirements are thrust upon people without adequate training in statistics and computing +- Errors are more easily introduced into long analysis pipelines +- Knowledge transfer is inhibited +- Results are difficult to replicate or reproduce +- Complicated analyses cannot be trusted + +## What Problem Does Reproducibility Solve? + +What we get: + +- Transparency +- Data Availability +- Software / Methods of Availability +- Improved Transfer of Knowledge + +What we do NOT get + +- Validity / Correctness of the analysis + +An analysis can be reproducible and still be wrong + +We want to know 'can we trust this analysis + +Does requiring reproducibility deter bad analysis? + +## Problems with Reproducibility + +The premise of reproducible research is that with data/code available, people can check each other and the whole system is self-correcting + +- Addresses the most "downstream" aspect of the research process -- Post-publication +- Assumes everyone plays by the same rules and wants to achieve the same goals (i.e. scientific discovery) + +## Who Reproduces Research? + +- For reproducibility to be effective as a means to check validity, someone needs to do something + - Re-run the analysis; check results match + - Check the code for bugs/errors + - Try alternate approaches; check sensitivity +- The need for someone to do something is inherited from traditional notion of replication +- Who is "someone" and what are their goals? + +## The Story So Far + +- Reproducibility brings transparency (wrt code+data) and increased transfer of knowledge +- A lot of discussion about how to get people to share data +- Key question of "can we trust this analysis"? is not addressed by reproducibility +- Reproducibility addresses potential problems long after they've occurred ("downstream") +- Secondary analyses are inevitably colored by the interests/motivations of others. + +## Evidence-based Data Analysis + +- Most data analyses involve stringing together many different tools and methods +- Some methods may be standard for a given field, but others are often applied ad hoc +- We should apply throughly studied (via statistical research), mutually agreed upon methods to analyze data whenever possible +- There should be evidence to justify the application of a given method + +## Evidence-based Data Analysis + +- Create analytic pipelines from evidence-based components - standardize it +- A deterministic statistical machine +- Once an evidence-based analytic pipeline is established, we shouldn't mess with it +- Analysis with a "transparent box" +- Reduce the "research degrees of freedom" +- Analogous to a pre-specified clinical trial protocol + +## Case Study: Estimating Acute Effects of Ambient Air Pollution Exposure + +- Acute / Short-term effects typically estimated via panel studies or time series studies +- Work originated in late 1970s early 1980s +- Key question "Are short-term changes in pollution associated with short-term changes in a population health outcome?" +- Studies are usually conducted at a community level +- Long history of statistical research investigating proper methods of analysis + +## Case Study: Estimating Acute Effects of Ambient Air Pollution Exposure + +- Can we encode everything that we have found in statistical / epidemiological research into a single package? +- Time series studies do not have a huge range of variation; typically involves similar types of data and similar questions +- We can create a deterministic statistical machine for this area? + +## DSM Modules for Time Series Studies of Air Pollution and Health + +1. Check for outliers, high leverage, overdispersion +2. Fill in missing data? No! +3. Model selection: Estimate degrees of freedom to adjust for unmeasured confounders + - Other aspects of model not as critical +4. Multiple lag analysis +5. Sensitivity analysis wrt + - Unmeasured confounder adjustment + - Influential points + +## Where to Go From Here? + +- One DSM is not enough, we need many! +- Different problems warrant different approaches and expertise +- A curated library of machines providing state-of-the-art analysis pipelines +- A CRAN/CPAN/CTAN/... for data analysis +- Or a "Cochrane Collaboration" for data analysis + +## A Curated Library of Data Analysis + +- Provide packages that encode data analysis pipelines for given problems, technologies, questions +- Curated by experts knowledgeable in the field +- Documentation / References given supporting module in the pipeline +- Changes introduced after passing relevant benchmarks/unit tests + +## Summary + +- Reproducible research is important, but does not necessarily solve the critical question of whether a data analysis is trustworthy +- Reproducible research focuses on the most "downstream" aspect of research documentation +- Evidence-based data analysis would provide standardized best practices for given scientific areas and questions +- Gives reviewers an important tool without dramatically increases the burden on them +- More effort should be put into improving the quality of "upstream" aspects of scientific research \ No newline at end of file diff --git a/content/notes/reproducibleresearch/week4.md b/content/notes/reproducibleresearch/week4.md new file mode 100644 index 0000000..1ce5fad --- /dev/null +++ b/content/notes/reproducibleresearch/week4.md @@ -0,0 +1,158 @@ +## The `cacher` Package for R + +- Add-on package for R +- Evaluates code written in files and stores immediate results in a key-value database +- R expressions are given SHA-1 hash values so that changes can be tracked and code reevaluated if necessary +- "Chacher packages" can be built for distribution +- Others can "clone" an analysis and evaluate subsets of code or inspect data objects + +The value of this is so other people can get the analysis or clone the analysis and look at subsets of the code. Or maybe more specifically data objects. People who want to run your code may not necessarily have the resources that you have. Because of that, they may not want to run the entire Markov chain Monte Carlo simulation that you did to get the posterior distribution or the histogram that you got at the end. + +But the idea is that you peel the onion a little bit rather than just go straight to the core. + +## Using `cacher` as an Author + +1. Parse the R source file; Create the necessary cache directiories and subdirectories +2. Cycle through each expression in the source file + - If an expression has never been evaluated, evaluate it and store any resulting R objects in the cache database + - If any cached results exists, lazy-load the results from the cache database and move to the next expression + - If an expression does not create any R objects (i.e, there is nothing to cache), add the expression to the list of expressions where evaluation needs to be forced + - Write out metadata for this expression to the metadata file + +- The `cachepackage` function creates a `cacher` package storing + - Source File + - Cached data objects + - Metadata +- Package file is zipped and can be distributed +- Readers can unzip the file and immediately investigate its contents via `cacher` package + +## Using `cacher` as a Reader + +A journal article says + +​ "... the code and data for this analysis can be found in the cacher package 092dcc7dda4b93e42f23e038a60e1d44dbec7b3f" + +```R +library(cacher) +clonecache(id = "092dcc7dda4b93e42f23e038a60e1d44dbec7b3f") +clonecache(id = "092d") ## Same as above +# Created cache directory `.cache` +showfiles() +# [1] "top20.R" +sourcefile("top20.R") +``` + +## Cloning an Analysis + +- Local directories are created +- Source code files and metadata are downloaded +- Data objects are *not* downloaded by default (may be really large) +- References to data objects are loaded and corresponding data can be lazy-loaded on demand + +`graphcode()` gives a node graph representing the code + +## Running Code + +- The `runcode` function executes code in the source file +- By default, expressions that results in an object being created are not run and the resulting objects is lazy-loaded into the workspace +- Expressions not resulting in objects are evaluated + +## Checking Code and Objects + +- The `checkcode` function evaluates all expressions from scratch (no lazy-loading) +- Results of evaluation are checked against stored results to see if the results are the same as what the author calculated + - Setting RNG seeds is critical for this to work +- The integrity of data objects can be verified with the `checkobjects` function to check for possible corruption of data perhaps during transit. + +You can inspect data objects with `loadcache`. This loads in pointers to each of the data objects into the workspace. Once you access the object, it will transfer it from the cache. + +## `cacher` Summary + +- The `cacher` package can be used by authors to create cache packages from data analyses for distribution +- Readers can use the `cacher` package to inspect others' data analyses by examing cached computations +- `cacher` is mindful of readers' resources and efficiently loads only those data objects that are needed. + +# Case Study: Air Pollution + +Particulate Matter -- PM + +When doing air pollution studies you're looking at particulate matter pollution. The dust is not just one monolithic piece of dirt or soot but it's actually composed of many different chemical constituents. + +Metals inert things like salts and other kinds of components so there's a possibility that a subset of those constituents are really harmful elements. + +PM is composed of many different chemical constituents and it's important to understand that the Environmental Protection Agency (EPA) monitors the chemical constituents of particulate matter and has been doing so since 1999 or 2000 on a national basis. + +## What causes PM to be Toxic? + +- PM is composed of many different chemical elements +- Some components of PM may be more harmful than others +- Some sources of PM may be more dangerous than others +- Identifying harmful chemical constituents may lead us to strategies for controlling sources of PM + +## NMMAPS + +- The National Morbidity, Mortality, and Air Pollution Study (NMMAPS) was a national study of the short-term health effects of ambient air pollution + +- Focused primarily on particulate matter ($PM_{10}$) and Ozone ($O_3$) + +- Health outcomes include mortality from all causes and hospitalizations for cardiovascular and respiratory diseases + +- Key publications + + - http://www.ncbi.nlm.nih.gov/pubmed/11098531 + - http://www.ncbi.nlm.nih.gov/pubmed/11354823 + +- Funded by the Heath Effects Institute + + - Roger Peng currently serves on the Health Effects Institute Health Review Committee + + ​ + +## NMMAPS and Reproducibility + +- Data made available at the Internet-based Health and Air Pollution Surveillance System (http://www.ihapss.jhsph.edu) +- Research and software also available at iHAPSS +- Many studies (over 67 published) have been conducted based on the public data http://www.ncbi.nlm.nih.gov/pubmed/22475833 +- Has served as an important test bed for methodological development + +## What Causes Particulate Matter to be Toxic? + +http://www.ncbi.nlm.nih.gov/pmc/articles/PMC1665439 + +- Lippmann et al. found strong evidence that NI modified the short-term effect of $PM_{10}$ across 60 US communities +- No other PM chemical constituent seemed to have the same modifying effect +- To simple to be true? + +## A Reanalysis of the Lippmann et al. Study + +http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2137127 + +- Rexamine the data from NMMAPS and link with PM chemical constituent data +- Are the findings sensitive for levels of Nickel in New York City? + +## Does Nickel Make PM Toxic? + +- Long-term average nickel concentrations appear correlated with PM risk +- There appear to be some outliers on the right-hand side (New York City) + +## Does Nickel Make PM Toxic? + +One of the most important things about those three points to the right is those are called high leverage points. So the regression line can be very senstive to high leverage points. Removing those three points from the dataset brings the regression line's slope down a little bit. Which then produces a line that is no longer statistical significant (p-value about 0.31) + +## What Have We Learned? + +- New York does have very high levels of nickel and vanadium, much higher than any other US community +- There is evidence of a positive relationship between NI concentrations and $PM_{10}$ risk +- The strength of this relationship is highly sensitive to the observations from New York City +- Most of the information in the data is derived from just 3 observations + +## Lessons Learned + +- Reproducibility of NMMAPS allowed for a secondary analysis (and linking with PM chemical constituent data) investigating a novel hypothesis (Lippmann et al.) +- Reproducibility also allowed for a critique of that new analysis and some additional new analysis (Dominici et al.) +- Original hypothesis not necessarily invalidated, but evidence not as strong as originally suggested (more work should be done) +- Reproducibility allows for the scientific discussion to occur in a timely and informed manner +- This is how science works. + + + diff --git a/content/notes/stat381.md b/content/notes/stat381.md new file mode 100644 index 0000000..146b80f --- /dev/null +++ b/content/notes/stat381.md @@ -0,0 +1,20 @@ +--- +title: Probability and Statistical Inference +showthedate: false +--- + + + +# Probability and Statistical Inference + +In the Fall of 2017, I took the course STAT 381 with Dr. Debra Hydorn. Below I included the interesting labs we worked on in the class. + +*Please note that these reports were not formatted for this site. So equations and images may not show up.* + +[Random Walk](randomwalk) + +[Random Number Generation](randomnumber) + +[Central Limit Theorum](centrallimit) + +[Confidence Interval](confint) diff --git a/content/notes/stat381/centrallimit.md b/content/notes/stat381/centrallimit.md new file mode 100644 index 0000000..440b2c8 --- /dev/null +++ b/content/notes/stat381/centrallimit.md @@ -0,0 +1,407 @@ +# Central Limit Theorem Lab + +**Brandon Rozek** + +## Introduction + +The Central Limit Theorem tells us that if the sample size is large, then the distribution of sample means approach the Normal Distribution. For distributions that are more skewed, a larger sample size is needed, since that lowers the impact of extreme values on the sample mean. + +### Skewness + +Skewness can be determined by the following formula +$$ +Sk = E((\frac{X - \mu}{\sigma})^3) = \frac{E((X - \mu)^3)}{\sigma^3} +$$ +Uniform distributions have a skewness of zero. Poisson distributions however have a skewness of $\lambda^{-\frac{1}{2}}$. + +In this lab, we are interested in the sample size needed to obtain a distribution of sample means that is approximately normal. + +### Shapiro-Wilk Test + +In this lab, we will test for normality using the Shapiro-Wilk test. The null hypothesis of this test is that the data is normally distributed. The alternative hypothesis is that the data is not normally distributed. This test is known to favor the alternative hypothesis for a large number of sample means. To circumvent this, we will test normality starting with a small sample size $n$ and steadily increase it until we obtain a distribution of sample means that has a p-value greater than 0.05 in the Shapiro-Wilk test. + +This tells us that with a false positive rate of 5%, there is no evidence to suggest that the distribution of sample means don't follow the normal distribution. + +We will use this test to look at the distribution of sample means of both the Uniform and Poisson distribution in this lab. + +### Properties of the distribution of sample means + +The Uniform distribution has a mean of $0.5$ and a standard deviation of $\frac{1}{\sqrt{12n}}$ and the Poisson distribution has a mean of $\lambda$ and a standard deviation of $\sqrt{\frac{\lambda}{n}}$. + +## Methods + +For the first part of the lab, we will sample means from a Uniform distribution and a Poisson distribution of $\lambda = 1$ both with a sample size $n = 5$. + +Doing so shows us how the Uniform distribution is roughly symmetric while the Poisson distribution is highly skewed. This begs the question: what sample size $(n)$ do I need for the Poisson distribution to be approximately normal? + +### Sampling the means + +The maximum number of mean observations that the Shapiro-Wilk test allows is 5000 observations. Therefore, we will obtain `n` observations separately from both the Uniform or Poisson distribution and calculate the mean from it. Repeating that process 5000 times. + +The mean can be calculated from the following way +$$ +Mean = \frac{\sum x_i}{n} +$$ +Where $x_i$ is the observation obtained from the Uniform or Poisson distribution + +### Iterating with the Shapiro-Wilk Test + +Having a sample size of a certain amount doesn't always guarantee that it will fail to reject the Shapiro-Wilk test. Therefore, it is useful to run the test multiple times so that we can create a 95th percentile of sample sizes that fails to reject the Shapiro-Wilk test. + +The issue with this is that lower lambda values result in higher skewness's. Which is described by the skewness formula. If a distribution has a high degree of skewness, then it will take a larger sample size n to make the sample mean distribution approximately normal. + +Finding large values of n result in longer computational time. Therefore, the code takes this into account by starting at a larger value of n and/or incrementing by a larger value of n each iteration. Incrementing by a larger value of n decreases the precision, though that is the compromise I'm willing to take in order to achieve faster results. + +Finding just the first value of $n$ that generates the sample means that fails to reject the Shapiro-Wilk test doesn't tell us much in terms of the sample size needed for the distribution of sample means to be approximately normal. Instead, it is better to run this process many times, finding the values of n that satisfy this condition multiple times. That way we can look at the distribution of sample sizes required and return back the 95th percentile. + +Returning the 95th percentile tells us that 95% of the time, it was the sample size returned or lower that first failed to reject the Shapiro-Wilk test. One must be careful, because it can be wrongly interpreted as the sample size needed to fail to reject the Shapiro-Wilk test 95% of the time. Using that logic requires additional mathematics outside the scope of this paper. Returning the 95th percentile of the first sample size that failed to reject the Shapiro-Wilk test, however, will give us a good enough estimate for a sample size needed. + +### Plots + +Once a value for `n ` is determined, we sample the means of the particular distribution (Uniform/Poisson) and create histograms and Q-Q plots for each of the parameters we're interested in. We're looking to verify that the histogram looks symmetric and that the points on the Q-Q Plot fit closely to the Q-Q Line with one end of the scattering of points on the opposite side of the line as the other. + + + +## Results + +### Part I + +Sampling the mean of the uniform distribution with $n = 5$ results in a mean of $\bar{x} = 0.498$ and standard deviation of $sd = 0.1288$. The histogram and Q-Q Plot can be seen in Figure I and Figure II respectively. + +$\bar{x}$ isn't far from the theoretical 0.5 and the standard deviation is also close to +$$ +\frac{1}{\sqrt{12(5)}} \approx 0.129 +$$ +Looking at the histogram and Q-Q plot, it suggests that data is approximately normal. Therefore we can conclude that a sample size of 5 is sufficient for the sample mean distribution coming from the normal distribution to be approximately normal. + +Sampling the mean of the Poisson distribution with $n = 5$ and $\lambda = 1$ results in a mean of $\bar{x} = 0.9918$ and a standard deviation of $sd = 0.443$. The histogram and Q-Q Plot can be seen in Figures III and IV respectively. + +$\bar{x}$ is not too far from the theoretical $\lambda = 1$, the standard deviation is a bit farther from the theoretical +$$ +\sqrt{\frac{\lambda}{n}} = \sqrt{\frac{1}{5}} = 0.447 +$$ +Looking at the Figures, however, shows us that the data does not appear normal. Therefore, we cannot conclude that 5 is a big enough sample size for the Poisson Distribution of $\lambda = 1$ to be approximately normal. + +### Part II + +Running the algorithm I described, I produced the following table + +| $\lambda$ | Skewness | Sample Size Needed | Shapiro-Wilk P-Value | Average of Sample Means | Standard Deviation of Sample Means | Theoretical Standard Deviation of Sample Means | +| --------- | -------- | ------------------ | -------------------- | ----------------------- | ---------------------------------- | ---------------------------------------- | +| 0.1 | 3.16228 | 2710 | 0.05778 | 0.099 | 0.0060 | 0.0061 | +| 0.5 | 1.41421 | 802 | 0.16840 | 0.499 | 0.0250 | 0.0249 | +| 1 | 1.00000 | 215 | 0.06479 | 1.000 | 0.0675 | 0.0682 | +| 5 | 0.44721 | 53 | 0.12550 | 4.997 | 0.3060 | 0.3071 | +| 10 | 0.31622 | 31 | 0.14120 | 9.999 | 0.5617 | 0.5679 | +| 50 | 0.14142 | 10 | 0.48440 | 50.03 | 2.2461 | 2.2361 | +| 100 | 0.10000 | 6 | 0.47230 | 100.0027 | 4.1245 | 4.0824 | + +The skewness was derived from the formula in the first section while the sample size was obtained by looking at the .95 blue quantile line in Figures XVIII-XIV. The rest of the columns are obtained from the output of the R Code function `show_results`. + +Looking at the histograms and Q-Q Plots produced by the algorithm, the distribution of sample means distributions are all roughly symmetric. The sample means are also tightly clustered around the Q-Q line, showing that the normal distribution is a good fit. This allows us to be confident that using these values of `n` as the sample size would result in the distribution of sample means of Uniform or Poisson (with a given lambda) to be approximately normal. + +All the values of the average sampling means are within 0.001 of the theoretical average of sample means. The standard deviation of sample means slightly increase as the value of $\lambda$ increases, but it still is quite low. + +## Conclusion + +The table in the results section clearly show that as the skewness increases, so does the sample size needed to make the distribution of sample means approximately normal. This shows the central limit theorem in action in that no matter the skewness, if you obtain a large enough sample, the distribution of sample means will be approximately normal. + +These conclusions pave the way for more interesting applications such as hypothesis testing and confidence intervals. + +## Appendix + +### Figures + +#### Figure I, Histogram of Sample Means coming from a Uniform Distribution with sample size of 5 + +![part1histunif](/home/rozek/Pictures/stat381lab3/part1histunif.png) + +#### Figure II, Q-Q Plot of Sample Means coming from a Uniform Distribution with sample size of 5 + +![part1qunif](/home/rozek/Pictures/stat381lab3/part1qunif.png) + +#### Figure III, Histogram of Sample Means coming from a Poisson Distribution with $\lambda = 1$ and sample size of 5 + +![part1histpoisson](/home/rozek/Pictures/stat381lab3/part1histpoisson.png) + +#### Figure IV, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 5 + +![part1qpoisson](/home/rozek/Pictures/stat381lab3/part1qpoisson.png) + +#### Figure V, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 0.1$ and sample size of 2710 + +![histpoisson01](/home/rozek/Pictures/stat381lab3/histpoisson01.png) + +#### Figure VI, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 0.1$ and sample size of 2710 + +![qpoisson01](/home/rozek/Pictures/stat381lab3/qpoisson01.png) + +#### Figure VII, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 0.5$ and sample size of 516 + +![histpoisson05](/home/rozek/Pictures/stat381lab3/histpoisson05.png) + +#### Figure VII, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 0.5$ and sample size of 516 + +![qpoisson05](/home/rozek/Pictures/stat381lab3/qpoisson05.png) + +#### Figure VIII, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 215 + +![histpoisson1](/home/rozek/Pictures/stat381lab3/histpoisson1.png) + +#### Figure IX, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 215 + +![qpoisson1](/home/rozek/Pictures/stat381lab3/qpoisson1.png) + +#### Figure X, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 5$ and sample size of 53 + +![histpoisson5](/home/rozek/Pictures/stat381lab3/histpoisson5.png) + +#### Figure XI, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 5$ and sample size of 53 + +![qpoisson5](/home/rozek/Pictures/stat381lab3/qpoisson5.png) + +#### Figure XII, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 10$ and sample size of 31 + +![histpoisson10](/home/rozek/Pictures/stat381lab3/histpoisson10.png) + +#### Figure XIII, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 10$ and sample size of 31 + +![qpoisson10](/home/rozek/Pictures/stat381lab3/qpoisson10.png) + +#### Figure XIV, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 50$ and sample size of 10 + +![histpoisson50](/home/rozek/Pictures/stat381lab3/histpoisson50.png) + +#### Figure XV, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 50$ and sample size of 10 + +![qpoisson50](/home/rozek/Pictures/stat381lab3/qpoisson50.png) + +#### Figure XVI, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 100$ and sample size of 6 + +![histpoisson100](/home/rozek/Pictures/stat381lab3/histpoisson100.png) + +#### Figure XVII, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 100$ and sample size of 6 + +![qpoisson100](/home/rozek/Pictures/stat381lab3/qpoisson100.png) + +#### Figure XVIII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 0.1$ + +![histl01](/home/rozek/Pictures/stat381lab3/histl01.png) + +#### Figure XIX, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 0.5$ + +![histl05](/home/rozek/Pictures/stat381lab3/histl05.png) + +#### Figure XX, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 1$ + +![histl1.0](/home/rozek/Pictures/stat381lab3/histl1.0.png) + +#### Figure XXI, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 5$ + +![histl5](/home/rozek/Pictures/stat381lab3/histl5.png) + +####Figure XXII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 10$ + +![histl10](/home/rozek/Pictures/stat381lab3/histl10.png) + +####Figure XXIII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 50$ + +![histl50](/home/rozek/Pictures/stat381lab3/histl50.png) + +#### Figure XXIV, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 100$ + +![histl100](/home/rozek/Pictures/stat381lab3/histl100.png) + +### R Code + +```R +rm(list=ls()) +library(ggplot2) + +sample_mean_uniform = function(n) { + xbarsunif = numeric(5000) + for (i in 1:5000) { + sumunif = 0 + for (j in 1:n) { + sumunif = sumunif + runif(1, 0, 1) + } + xbarsunif[i] = sumunif / n + } + xbarsunif +} + +sample_mean_poisson = function(n, lambda) { + xbarspois = numeric(5000) + for (i in 1:5000) { + sumpois = 0 + for (j in 1:n) { + sumpois = sumpois + rpois(1, lambda) + } + xbarspois[i] = sumpois / n + } + xbarspois +} + + +poisson_n_to_approx_normal = function(lambda) { + print(paste("Looking at Lambda =", lambda)) + ns = c() + + # Speed up computation of lower lambda values by starting at a different sample size + # and/or lowering the precision by increasing the delta sample size + # and/or lowering the number of sample sizes we obtain from the shapiro loop + increaseBy = 1; + iter = 3; + startingValue = 2 + if (lambda == 0.1) { + startingValue = 2000; + iter = 3; + increaseBy = 50; + } else if (lambda == 0.5) { + startingValue = 200; + iter = 5; + increaseBy = 10; + } else if (lambda == 1) { + startingValue = 150; + iter = 25; + } else if (lambda == 5) { + startingValue = 20; + iter = 50; + startingValue = 10; + } else if (lambda == 10) { + iter = 100; + } else { + iter = 500; + } + + progressIter = 1 + for (i in 1:iter) { + + # Include a progress indicator for personal sanity + if (i / iter > .1 * progressIter) { + print(paste("Progress", i / iter * 100, "% complete")) + progressIter = progressIter + 1 + } + + n = startingValue + + dist = sample_mean_poisson(n, lambda) + p.value = shapiro.test(dist)$p.value + while (p.value < 0.05) { + n = n + increaseBy + dist = sample_mean_poisson(n, lambda) + p.value = shapiro.test(dist)$p.value + + # More sanity checks + if (n %% 10 == 0) { + print(paste("N =", n, " p.value =", p.value)) + } + } + ns = c(ns, n) + } + + print(ggplot(data.frame(ns), aes(x = ns)) + + geom_histogram(fill = 'white', color = 'black', bins = 10) + + geom_vline(xintercept = ceiling(quantile(ns, .95)), col = '#0000AA') + + ggtitle(paste("Histogram of N needed for Poisson distribution of lambda =", lambda)) + + xlab("N") + + ylab("Count") + + theme_bw()) + + + ceiling(quantile(ns, .95)) #95% of the time, this value of n will give you a sampling distribution that is approximately normal +} + +uniform_n_to_approx_normal = function() { + ns = c() + progressIter = 1 + + for (i in 1:500) { + + # Include a progress indicator for personal sanity + if (i / 500 > .1 * progressIter) { + print(paste("Progress", i / 5, "% complete")) + progressIter = progressIter + 1 + } + + n = 2 + dist = sample_mean_uniform(n) + p.value = shapiro.test(dist)$p.value + while (p.value < 0.05) { + n = n + 1 + dist = sample_mean_uniform(n) + p.value = shapiro.test(dist)$p.value + + if (n %% 10 == 0) { + print(paste("N =", n, " p.value =", p.value)) + } + + } + + ns = c(ns, n) + } + + print(ggplot(data.frame(ns), aes(x = ns)) + + geom_histogram(fill = 'white', color = 'black', bins = 10) + + geom_vline(xintercept = ceiling(quantile(ns, .95)), col = '#0000AA') + + ggtitle("Histogram of N needed for Uniform Distribution") + + xlab("N") + + ylab("Count") + + theme_bw()) + + ceiling(quantile(ns, .95)) #95% of the time, this value of n will give you a sampling distribution that is approximately normal +} + + + +show_results = function(dist) { + print(paste("The mean of the sample mean distribution is:", mean(dist))) + print(paste("The standard deviation of the sample mean distribution is:", sd(dist))) + print(shapiro.test(dist)) + print(ggplot(data.frame(dist), aes(x = dist)) + + geom_histogram(fill = 'white', color = 'black', bins = 20) + + ggtitle("Histogram of Sample Means") + + xlab("Mean") + + ylab("Count") + + theme_bw()) + qqnorm(dist, pch = 1, col = '#001155', main = "QQ Plot", xlab = "Sample Data", ylab = "Theoretical Data") + qqline(dist, col="#AA0000", lty=2) +} + + +## PART I +uniform_mean_dist = sample_mean_uniform(n = 5) +poisson_mean_dist = sample_mean_poisson(n = 5, lambda = 1) + +show_results(uniform_mean_dist) +show_results(poisson_mean_dist) + +## PART II + +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 0.1"); +n.01 = poisson_n_to_approx_normal(0.1) +show_results(sample_mean_poisson(n.01, 0.1)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 0.5"); +n.05 = poisson_n_to_approx_normal(0.5) +show_results(sample_mean_poisson(n.05, 0.5)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 1"); +n.1 = poisson_n_to_approx_normal(1) +show_results(sample_mean_poisson(n.1, 1)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 5"); +n.5 = poisson_n_to_approx_normal(5) +show_results(sample_mean_poisson(n.5, 5)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 10"); +n.10 = poisson_n_to_approx_normal(10) +show_results(sample_mean_poisson(n.10, 10)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 50"); +n.50 = poisson_n_to_approx_normal(50) +show_results(sample_mean_poisson(n.50, 50)) +print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 100"); +n.100 = poisson_n_to_approx_normal(100) +show_results(sample_mean_poisson(n.100, 100)) + +print("Starting Algorithm to Find Sample Size Needed for the Uniform Distribution") +n.uniform = uniform_n_to_approx_normal() +show_results(sample_mean_uniform(n.uniform)) +``` + diff --git a/content/notes/stat381/confint.md b/content/notes/stat381/confint.md new file mode 100644 index 0000000..9ed0f73 --- /dev/null +++ b/content/notes/stat381/confint.md @@ -0,0 +1,287 @@ +# Confidence Interval Lab + +**Written by Brandon Rozek** + +## Introduction + +Confidence intervals expands the concept of a point estimation by giving a margin of error such that one can be confident that a certain percentage of the time the true parameter falls within that interval. + +In this lab, we will look at confidence intervals for a mean. This lab focuses on a certain method of confidence intervals that depends on the distribution of sample means being Normal. We will show how the violation of this assumption impacts the probability that the true parameter falls within the interval. + +## Methods + +The observed level of confidence tells us the proportion of times the true mean falls within a confidence interval. To show how the violation of the Normality assumption affects this, we will sample from both a Normal distribution, T distribution, and exponential distribution with different sample sizes. + +The normal and T distributions are sampled with a mean of 5 and a standard deviation of 2. The exponential deviation is sampled with a lambda of 2 or mean of 0.5. + +From the samples, we obtain the mean and the upper/lower bounds of the confidence interval. This is performed 100,000 times. That way we obtain a distribution of these statistics. + +We know that a confidence interval is valid, if the lower bound is no more than the true mean and the upper bound is no less than the true mean. From this definition, we can compute a proportion of observed confidence from the simulations + +### Visualizations + +From the distributions of statistics, we can create visualizations to support the understanding of confidence intervals. + +The first one is a scatterplot of lower bounds vs upper bounds. This plot demonstrates the valid confidence intervals in blue and the invalid ones in red. It demonstrates how confidence intervals that are invalid are not located inside the box. + +The second visualization is a histogram of all the sample means collected. The sample means that didn't belong to a valid confidence interval are shaded in red. This graphic helps demonstrate the type I errors on both sides of the distribution. + +In this lab, we're interested in seeing how our observed level of confidence differs from our theoretical level of confidence (95%) when different sample sizes and distributions are applied. + +## Results + +We can see from the table section in the Appendix that sampling from a Normal or t distribution does not adversely affect our observed level of confidence. The observed level of confidence varies slightly from the theoretical level of confidence of 0.95. + +When sampling from the exponential distribution, however, the observed level of confidence highly depends upon the sample size. + +Looking at Table III, we can see that for a sample size of 10, the observed level of confidence is at a meager 90%. This is 5% off from our theoretical level of confidence. This shows how the normality assumption is vital to the precision of our estimate. + +This comes from the fact that using this type of confidence interval on a mean from a non-normal distribution requires a large sample size for the central limit theorem to take affect. + +The central limit theorem states that if the sample size is "large", the distribution of sample means approach the normal distribution. You can see how in Figure XVIII, the distribution of sample means is skewed, though as the sample size increases, the distribution of sample means become more symmetric (Figure XIX). + +## Conclusion + +From this, we can conclude that violating the underlying assumption of normality decreases the observed level of confidence. We can mitigate the decrease of the observed level of confidence when sampling means from a non-normal distribution by having a larger sample size. This is due to the central limit theorem. + +## Appendix + +### Tables + +#### Table I. Sampling from Normal + +| Sample Size | Proportion of Means Within CI | +| ----------- | ----------------------------- | +| 10 | 0.94849 | +| 20 | 0.94913 | +| 50 | 0.95045 | +| 100 | 0.94955 | + + + +#### Table II. Sampling from T Distribution + +| Sample Size | Proportion of Means Within CI | +| ----------- | ----------------------------- | +| 10 | 0.94966 | +| 20 | 0.94983 | +| 50 | 0.94932 | +| 100 | 0.94999 | + + + +#### Table III. Sampling from Exponential Distribution + +| Sample Size | Proportion of Means Within CI | +| ----------- | ----------------------------- | +| 10 | 0.89934 | +| 20 | 0.91829 | +| 50 | 0.93505 | +| 100 | 0.94172 | + + + + + +### Figures + +#### Normal Distribution + +##### Figure I. Scatterplot of Bounds for Normal Distribution of Sample Size 10 + +![normal10scatter](/home/rozek/Pictures/statlab4/normal10scatter.png) + +##### Figure II. Histogram of Sample Means for Normal Distribution of Sample Size 10 + +![normal10hist](/home/rozek/Pictures/statlab4/normal10hist.png) + +##### Figure III. Scatterplot of Bounds for Normal Distribution of Sample Size 20 + +![normal20scatterplot](/home/rozek/Pictures/statlab4/normal20scatterplot.png) + +##### Figure IV. Histogram of Sample Means for Normal Distribution of Sample Size 20 + +![normal20hist](/home/rozek/Pictures/statlab4/normal20hist.png) + +##### Figure VScatterplot of Bounds for Normal Distribution of Sample Size 50 + +![normal50scatterplot](/home/rozek/Pictures/statlab4/normal50scatterplot.png) + +##### Figure VI. Histogram of Sample Means for Normal Distribution of Sample Size 50 + +![normal50hist](/home/rozek/Pictures/statlab4/normal50hist.png) + +##### Figure VII. Scatterplot of Bounds for Normal Distribution of Sample Size 100 + +![normal100scatterplot](/home/rozek/Pictures/statlab4/normal100scatterplot.png) + +##### Figure VIII. Histogram of Sample Means for Normal Distribution of Sample Size 100 + +![normal100hist](/home/rozek/Pictures/statlab4/normal100hist.png) + +#### T Distribution + +##### Figure IX. Scatterplot of Bounds for T Distribution of Sample Size 10 + +![t10scatterplot](/home/rozek/Pictures/statlab4/t10scatterplot.png) + +##### Figure X. Histogram of Sample Means for T Distribution of Sample Size 10 + +![t10hist](/home/rozek/Pictures/statlab4/t10hist.png) + +##### Figure XI. Scatterplot of Bounds for T Distribution of Sample Size 20 + +![t20scatterplot](/home/rozek/Pictures/statlab4/t20scatterplot.png) + +##### Figure XII. Histogram of Sample Means for T Distribution of Sample Size 20 + +![t20hist](/home/rozek/Pictures/statlab4/t20hist.png) + +##### Figure XIII. Scatterplot of Bounds for T Distribution of Sample Size 50 + +![t50scatter](/home/rozek/Pictures/statlab4/t50scatter.png) + +##### Figure XIV. Histogram of Sample Means for T Distribution of Sample Size 50 + +![t50hist](/home/rozek/Pictures/statlab4/t50hist.png) + +##### Figure XV. Scatterplot of Bounds for T Distribution of Sample Size 100 + +![t100scatter](/home/rozek/Pictures/statlab4/t100scatter.png) + +##### Figure XVI. Histogram of Sample Means for T Distribution of Sample Size 100 + +![t100hist](/home/rozek/Pictures/statlab4/t100hist.png) + +#### Exponential Distribution + +##### Figure XVII. Scatterplot of Bounds for Exponential Distribution of Sample Size 10 + +![exp10scatter](/home/rozek/Pictures/statlab4/exp10scatter.png) + +##### Figure XVIII. Histogram of Sample Means for Exponential Distribution of Sample Size 10 + +![exp10hist](/home/rozek/Pictures/statlab4/exp10hist.png) + +##### Figure XIX. Scatterplot of Bounds for Exponential Distribution of Sample Size 20 + +![exp20scatter](/home/rozek/Pictures/statlab4/exp20scatter.png) + +##### Figure XX. Histogram of Sample Means for Exponential Distribution of Sample Size 20 + +![exp20hist](/home/rozek/Pictures/statlab4/exp20hist.png) + +##### Figure XXI. Scatterplot of Bounds for Exponential Distribution of Sample Size 50 + +![exp50scatter](/home/rozek/Pictures/statlab4/exp50scatter.png) + +##### Figure XXII. Histogram of Sample Means for Exponential Distribution of Sample Size 50 + +![exp50hist](/home/rozek/Pictures/statlab4/exp50hist.png) + +##### Figure XXIII. Scatterplot of Bounds for Exponential Distribution of Sample Size 100 + +![exp100scatter](/home/rozek/Pictures/statlab4/exp100scatter.png) + +##### Figure XXIV. Histogram of Sample Means for Exponential Distribution of Sample Size 100 + +![exp100hist](/home/rozek/Pictures/statlab4/exp100hist.png) + + + +### R Code + +```R +rm(list=ls()) +library(ggplot2) +library(functional) # For function currying + +proportion_in_CI = function(n, mu, dist) { + + # Preallocate vectors + lower_bound = numeric(100000) + upper_bound = numeric(100000) + means = numeric(100000) + + number_within_CI = 0 + + ME = 1.96 * 2 / sqrt(n) ## Normal Margin of Error + + for (i in 1:100000) { + x = numeric(n) + + # Sample from distribution + if (dist == "Normal" | dist == "t") { + x = rnorm(n,mu,2) + } else if (dist == "Exponential") { + x = rexp(n, 1 / mu) + } + + ## Correct ME if non-normal + if (dist != "Normal") { + ME = qt(0.975,n-1)*sd(x)/sqrt(n) + } + + ## Store statistics + means[i] = mean(x) + lower_bound[i] = mean(x) - ME + upper_bound[i] = mean(x) + ME + + # Is Confidence Interval Valid? + if (lower_bound[i] < mu & upper_bound[i] > mu) { + number_within_CI = number_within_CI + 1 + } + } + + # Prepare for plotting + lbub = data.frame(lower_bound, upper_bound, means) + lbub$col = ifelse(lbub$lower_bound < mu & lbub$upper_bound > mu, 'Within CI', 'Outside CI') + print(ggplot(lbub, aes(x = lower_bound, y = upper_bound, col = col)) + + geom_point(pch = 1) + + geom_hline(yintercept = mu, col = '#000055') + + geom_vline(xintercept = mu, col = '#000055') + + ggtitle(paste("Plot of Lower Bounds vs Upper Bounds with Sample Size of ", n)) + + xlab("Lower Bound") + + ylab("Upper Bounds") + + theme_bw() + ) + print(ggplot(lbub, aes(x = means, fill = col)) + + geom_histogram(color = 'black') + + ggtitle(paste("Histogram of Sample Means with Sample Size of ", n)) + + xlab("Sample Mean") + + ylab("Count") + + theme_bw() + ) + + # Return proportion within CI + number_within_CI / 100000 +} + +sample_sizes = c(10, 20, 50, 100) + +### PART I +proportion_in_CI_Normal = Curry(proportion_in_CI, dist = "Normal", mu = 5) +p_norm = sapply(sample_sizes, proportion_in_CI_Normal) +sapply(p_norm, function(x) { + cat("The observed proportion of intervals containing mu is", x, "\n") + invisible(x) +}) + + +### PART II +proportion_in_CI_T = Curry(proportion_in_CI, dist = "t", mu = 5) +p_t = sapply(sample_sizes, proportion_in_CI_T) +sapply(p_t, function(x) { + cat("The observed proportion of intervals containing mu is", x, "\n") + invisible(x) +}) + +### PART III +proportion_in_CI_Exp = Curry(proportion_in_CI, dist = "Exponential", mu = 0.5) +p_exp = sapply(sample_sizes, proportion_in_CI_Exp) +sapply(p_exp, function(x) { + cat("The observed proportion of intervals containing mu is", x, "\n") + invisible(x) +}) +``` + diff --git a/content/notes/stat381/randomnumber.md b/content/notes/stat381/randomnumber.md new file mode 100644 index 0000000..dcdb5d4 --- /dev/null +++ b/content/notes/stat381/randomnumber.md @@ -0,0 +1,441 @@ +# Random Number Generation + +## Introduction + +The generation of random numbers have a variety of applications including but not limited to the modeling of stochastic processes. It is important, therefore, to be able to generate any random number following a given distribution. One of the many ways to achieve this is to transform numbers sampled from a random uniform distribution. + +In this lab, we will compare the effectiveness between the linear congruence method (LCM), `runif`, and `rexp` to generate random numbers. The programming language R will be used and different plots and summary statistics are drawn upon to analyze the effectiveness of the methods. + +## Methods + +### The Linear Congruential Method + +The linear congruential method (LCM) is an algorithm that produces a sequence of pseudo-random numbers using the following recursive function +$$ +X_{n + 1} = (aX_n + c) \mod m +$$ +The R code we use has a `c` value of 0 which is a special case known as the multiplicative congruential generator (MCG). + +There are several conditions for using a MCG. First, the seed value must be co-prime to `m`. In other words, the greatest common denominator between the two must be 1. A function was written in R to check this. Secondly, `m` must be a prime number or a power of a prime number. + +#### Periodicity + +An element of periodicity comes into play when dealing with pseudo-random number generators. Once the generator has produced a certain number of terms, it is shown to loop back to the first term of the sequence. It is advantageous, therefore, to keep the period high. + +The period in a MCG is at most `m - 1`. In this lab, `m` has a value of $2^{31}$ and only 100 numbers were sampled from the LCM. This allows us to avoid the issue of periodicity entirely in our analysis. + +### Mersenne-Twister Method + +The default pseudo-random number generator (pseudo RNG) in R is the Mersenne-Twister with the default seed value of the current time and the process id of the current R instance. Mersenne-Twister is part of a class of pseudo RNG called the generalized feedback register. This class of pseudo RNGs provide a very long period (VLP) or in other words, a long cycle before the values start repeating. VLPs are often useful when executing large simulations in R. + +Since this method is already coded in the `base` R-package, we will leave the implementation for the curious to research. + +### The Uniform Distribution + +#### Probability Mass Function + +The uniform distribution function $Unif(\theta_1, \theta_2)$ has a probability mass function (PMF) of the following. +$$ +f(x) = \frac{1}{\theta_2 - \theta_1} +$$ +Where x is valid between [$\theta_1$, $\theta_2$]. + +In our case, we are producing numbers from [0,1]. We can therefore reduce the probability mass function to the following +$$ +f(x) = 1 +$$ +#### Expected Value + +The expected value can be defined as +$$ +E(X) = \int_a^b xf(x)dx +$$ +For the uniform distribution we're using that becomes +$$ +E(X) = \int_0^1 xdx = \frac{1}{2}[x^2]_0^1 = \frac{1}{2} +$$ +We should, therefore, expect the mean of the generated random number sequence to roughly equal $\frac{1}{2}$. + +#### Median + +To find the median of the distribution, we need to find the point at which the cumulative density function (CDF) is equal to .5. +$$ +\int_0^{Median(X)} f(x)dx = \frac{1}{2} +$$ +$$ +\int_0^{Median(X)} dx = \frac{1}{2} +$$ + +$$ +[X]_0^{Median(X)} = \frac{1}{2} +$$ + +$$ +Median(X) = \frac{1}{2} +$$ + +This shows us that the median of the distribution should be roughly equal to $\frac{1}{2}$ as well. + +#### Analysis of Uniform Distribution Fit + +The histogram of a uniform distribution of data should look rectangular in shape. This means that the counts of all the sub-intervals should be about the same. + +Another way to test whether or not the distribution is a good fit is to use what is called a Quantile-Quantile plot (Q-Q Plot). This is a probability plot that compares the quantiles from the theoretical distribution, this is the uniform distribution, to that of the sample. + +For a precise Q-Q Plot, we need a lot of quantiles to compare. In this lab, we will compare 100 different quantiles. The quantiles from the theoretical distribution can be easily derived from the fact that all value ranges are equally probable. The theoretical quantiles in this case is 0.01, 0.02, ..., 0.98, 0.99, 1. The sample quantiles are obtianed by receiving 100 observations from `runif` or the LCM. + +In the Q-Q plot, a good fit is shown when the points hug closely to the Q-Q line. It is also important to have symmetry in the points. This means that the points are ending on opposite sides of the Q-Q line. + +For sake of exploration, we will use 5 different seed values for the linear congruential method (while making sure that the seed values are co-prime). We will then use the results of these and compare LCM to how the standard `runif` method generates random numbers. + +### Exponential Distribution + +#### Probability Mass Function and the Cumulative Density Function + +The exponential distribution is a type of continuous distribution that is defined by the following PMF +$$ +f(x) = \lambda e^{-\lambda t} +$$ +We can find the CDF by taking the integral of the PMF. +$$ +F(x) = \int f(x)dx = \lambda \int e^{-\lambda x} dx = \lambda * (\frac{-1}{\lambda}) e^{-\lambda x} + C = -e^{-\lambda x} + C +$$ +One of the conditions for the cumulative density function is that as $x \to \infty$, $F(x) \to 1$. +$$ +1 = \lim_{x \to \infty} (-e^{-\lambda x} + C) = \lim_{x \to \infty} (-e^{-\lambda x}) + lim_{x \to \infty} ( C) = \lim_{x \to \infty}(-e^{\lambda x}) + C +$$ +This shows that $C = 1$, since $lim_{x \to \infty} (-e^{-\lambda x})$ is equal to 0. + +Substituting $C​$ gives us the following. +$$ +F(x) = 1 - e^{-\lambda x} +$$ + +#### Expected Value + +We can find the expected value using the formula described in the previous Expected Value section. Reflected in the bounds of integration is the domain of the exponential distribution $[0, \infty)$. +$$ +E(X) = \lim_{a \to \infty}\int_0^a x \lambda e^{-\lambda x} dx +$$ +The integral above features a product of two functions. So as an aside, we will derive a formula so we can take the integral above. + +The total derivative is defined as +$$ +d(uv) = udv + vdu +$$ + + +After taking the integral of both sides, we can solve for a formula that gives the following +$$ +\int d(uv) = \int udv + \int vdu +$$ + +$$ +\int udv = uv - \int vdu +$$ + +The formula above is called *Integration by Parts*. We will make use of this formula by defining $u = \lambda x$ and $dv = e^{-\lambda x} dx$ + +This implies that $du = \lambda dx$ and $v= -\frac{1}{\lambda}e^{-\lambda x}$ +$$ +E(X) = -\lim_{a \to \infty}[\lambda x \frac{1}{\lambda}e^{-\lambda x}]_0^a - \lim_{b \to \infty}\int_0^b -\frac{1}{\lambda}e^{-\lambda x}\lambda dx +$$ + +$$ +E(X) = -\lim_{a \to \infty} [xe^{-\lambda x}]_0^a - \lim_{b \to \infty}\int_0^b -e^{-\lambda x}dx +$$ + +$$ +E(X) = -\lim_{a \to \infty}(ae^{-\lambda a}) - \lim_{b \to \infty}[\frac{1}{\lambda}e^{-\lambda x}]_0^b +$$ + +$$ +E(X) = 0 - \frac{1}{\lambda}[\lim_{b \to \infty}(e^{-\lambda b}) - e^{-0\lambda}] +$$ + +$$ +E(X) = -\frac{1}{\lambda}(-1) = \frac{1}{\lambda} +$$ + +For the purposes of this lab, we will make the rate ($\lambda$) equal to 3. Which means we should expect our mean to be roughly equal to $\frac{1}{3}$. + +#### Median + +The median can be found by setting the CDF equal to $\frac{1}{2}$ +$$ +1- e^{-\lambda Median(X)} = \frac{1}{2} +$$ + +$$ +e^{-\lambda Median(X)} = \frac{1}{2} +$$ + +$$ +-\lambda Median(X) = \ln(\frac{1}{2}) +$$ + +$$ +Median(X) = \frac{\ln(2)}{\lambda} +$$ + +This shows that we should expect our median to be around $\frac{\ln(2)}{3} \approx 0.231$. + +### Inverse Transform Sampling + +Once we have a uniform distribution of values, we can then use these values to map to an exponential distribution. This is done through a technique called inverse transform sampling, the technique works as follows: + +1. Generate a random number u from the standard uniform distribution +2. Compute the value of X such that F(X) = u +3. The value of X belongs to the distribution of F + +Using these steps, we'll derive the exponential transform below. +$$ +F(X) = 1 - e^{-\lambda x} = u +$$ +Then proceeding to solve for X, we obtain the following. +$$ +e^{-\lambda X} = 1 - u +$$ + +$$ +-\lambda X = \ln(1 - u) +$$ + +$$ +X = \frac{-\ln(1 - u)}{\lambda} +$$ + +With this formula, we can now find values for X which is a random variable that follows an exponential distribution given random uniform data $u$. + +In this lab, we are looking at the exponential distribution with a rate of 3. Therefore, the probability mass function, the cumulative distribution function, and the exponential transform can be redefined as these respectively. +$$ +f(x) = 3e^{-3x} +$$ + +$$ +F(x) = 1 - e^{-3x} +$$ + +$$ +X = \frac{-\ln(1 - u)}{3} +$$ + +### R Code + +The R code makes use of the concepts above. The purpose of this code is to output the summary statistics, histograms, and Q-Q plots are used to compare the different methods. + +First the LCM is executed four times with three different seed values. The LCM is used to create a uniform distribution of data that is then compared to the standard `runif` function in the R language. + +Then, transformations of a LCM, `runif`, are executed and compared with the standard `rexp` to create an exponential distribution of data with $\lambda = 3$. + + + +## Results + +### Uniform Distribution + +For a small sample of 100 values, the data seems evenly distributed for all seeds and methods used. The peaks and troughs are more pronounced in the LCM methods suggesting that the `runif` command creates more evenly distributed data than the LCM. + +Deviations from the mean and median are lowest for the LCM rather than the standard `runif` command with the exception of the LCM with the seed of 93463. + +The Q-Q plots for all of the methods follow the Q-Q Line tightly and appear symmetric. + +### Exponential Distribution + +A bin size of 20 is used to make the histograms easily comparable to each other. One interesting thing to note is that in Figure XI, there is an observation located far out from the rest of the data. For the purpose of a histogram, which is to show us the shape of the distribution, this one far observation skews what we can see. Therefore the next figure, Figure XII has that single outlier removed and shows the histogram of the rest of the data. + +All of the histograms appear exponential in shape. Looking at the Q-Q plots, the LCM transformation and the `rexp` distribution of data fit closely to the QQ-Line. All of the Q-Q Plots have the points getting further away from the line as you get higher up in the percentiles. The `runif` transformation quantiles diverge from the line after about the 50th percentile. + +Deviations from the mean and median were about the same for both transformed techniques (`runif` and LCM). The `rexp` command did better when it came to the deviation from the mean, but performed worse when it came to deviation from the median. + +## Conclusion + +The linear congruential methods performed better when it came to simulating the distribution than the standard R functions. It more accurately captured the median for both the standard uniform data, and the exponential data. Against the `runif` command, it also performed better at simulating the mean. + +This can especially be seen when comparing the two transform techniques. The transformed LCM distribution of data followed the Q-Q line more tightly than the transformed `runif`. + +I speculate that this is due to the seed value used. The Mersenne-Twist method performs better when the seed value doesn't have many zeros in it. Since the seed value is determined by the system time and process id, we don't know for sure if it's a proper input for the Mersenne-Twist. For the LCM, seeds were properly tested to make sure that it was co-prime with one of its parameters. This condition allowed proper seeds to work well with the LCM. + +Further research can be done on standardizing the seed values used across all the different pseudo random number generators and looking at the 6 other pseudo RNG that comes built into R. Changing the seed and random number generator can be achieved through the `set.seed` function. + +## Appendix + +### Figures + +#### Figure I, Histogram of LCM Random Data with seed 55555 + +![](file:///home/rozek/Pictures/stat381lab2/hist55555.png) + +#### Figure II, Q-Q Plot of LCM Random Data with seed 55555 + +![qqplot55555](/home/rozek/Pictures/stat381lab2/qqplot55555.png) + +#### Figure III, Histogram of LCM Random Data with seed 93463 + +![hist93463](/home/rozek/Pictures/stat381lab2/hist93463.png) + +#### Figure IV, Q-Q Plot of LCM Random Data with seed 93463 + +![q93463](/home/rozek/Pictures/stat381lab2/q93463.png) + +#### Figure V, Histogram of LCM Random Data with seed 29345 + +![hist29345](/home/rozek/Pictures/stat381lab2/hist29345.png) + +#### Figure VI, Q-Q Plot of LCM Random Data with seed 29345 + +![q29345](/home/rozek/Pictures/stat381lab2/q29345.png) + + + +#### Figure VII, Histogram of LCM Random Data with seed 68237 + +![hist68237](/home/rozek/Pictures/stat381lab2/hist68237.png) + +#### Figure VIII, Q-Q Plot of LCM Random Data with seed 68237 + +![q68237](/home/rozek/Pictures/stat381lab2/q68237.png) + +#### Figure IX, Histogram of R Random Uniform Data + +![histunif](/home/rozek/Pictures/stat381lab2/histunif.png) + +#### Figure X, Q-Q Plot of R Random Uniform Data + +![qunif](/home/rozek/Pictures/stat381lab2/qunif.png) + +#### Figure XI, Histogram of Exponential Data from LCM Random + +![histexplcm](/home/rozek/Pictures/stat381lab2/histexplcm.png) + +#### Figure XII, Histogram of Exponential Data from LCM Random without Outlier Above 2 + +![histexplcm_nooutlier](/home/rozek/Pictures/stat381lab2/histexplcm_nooutlier.png) + +#### Figure XIII, Q-Q Plot of Exponential Data from LCM Rnadom + +![qexplcm](/home/rozek/Pictures/stat381lab2/qexplcm.png) + +#### Figure XIV, Histogram of Exponential Data from R Random Uniform + +![histexpunif](/home/rozek/Pictures/stat381lab2/histexpunif.png) + +#### Figure XV, Q-Q Plot of Exponential Data from R Random Uniform + +![qexpunif](/home/rozek/Pictures/stat381lab2/qexpunif.png) + +#### Figure XVI, Histogram of R Generated Exponential Data + +![histexp](/home/rozek/Pictures/stat381lab2/histexp.png) + +#### Figure XVII, Q-Q Plot of R Generated Exponential Data + +![qexp](/home/rozek/Pictures/stat381lab2/qexp.png) + +### Tables + +#### Table I, Uniform Distribution Sample Data + +| Method | Mean ($\bar{x}$) | Median ($\tilde{x}$) | $\mu - \bar{x}$ | $m - \tilde{x}$ | +| ------------------- | ---------------- | -------------------- | --------------- | --------------- | +| LCM with seed 55555 | 0.505 | 0.521 | -0.005 | -0.021 | +| LCM with seed 93463 | 0.452 | 0.402 | 0.048 | 0.098 | +| LCM with seed 29345 | 0.520 | 0.502 | -0.020 | -0.002 | +| LCM with seed 68237 | 0.489 | 0.517 | 0.011 | -0.017 | +| R Random Uniform | 0.480 | 0.471 | 0.020 | 0.029 | + +#### Table II, Exponential Distribution Sample Data + +| Method | Mean | Median | $\mu - \bar{x}$ | $m - \tilde{x}$ | +| --------------- | ----- | ------ | --------------- | --------------- | +| LCM Transform | 0.380 | 0.246 | -0.047 | -0.015 | +| RUnif Transform | 0.283 | 0.218 | 0.050 | 0.013 | +| R Exponential | 0.363 | 0.278 | -0.030 | -0.047 | + +### R Code + +```R +library(ggplot2) +linear_congruential = function(seed) { + a = 69069 + c = 0 + m = 2^31 + x = numeric(100) + x[1] = seed + for (i in 2:100) { + x[i] = (a * x[i-1] + c) %% m + } + xnew = x / (max(x) + 1) + xnew +} + +gcd = function(x,y) { + r = x %% y; + return(ifelse(r, gcd(y, r), y)) +} +check_seed = function(seed) { + if (gcd(seed, 2^31) == 1) { + print(paste("The seed value of", seed, "is co-prime")) + } else { + print(paste("The seed value of", seed, "is NOT co-prime")) + } +} + +check_data = function(data, distribution, title) { + print(paste("Currently looking at", title)) + print(summary(data)) + print(ggplot(data.frame(data), aes(x = data)) + + geom_histogram(fill = 'white', color = 'black', bins = 10) + + xlab("Date") + + ylab("Frequency") + + ggtitle(paste("Histogram of", title)) + + theme_bw()) + uqs = (1:100) / 100 + if (distribution == "Uniform") { + qqplot(data, uqs, pch = 1, col = '#001155', main = paste("QQ Plot of", title), xlab = "Sample Data", ylab = "Theoretical Data") + qqline(uqs, distribution = qunif, col="red", lty=2) + } else if (distribution == "Exponential") { + eqs = -log(1-uqs) / 3 + qqplot(data, eqs, pch = 1, col = '#001155', main = paste("QQ Plot of", title), xlab = "Sample Data", ylab = "Theoretical Data") + qqline(eqs, distribution=function(p) { qexp(p, rate = 3)}, col="#AA0000", lty=2) + } +} + +seed1 = 55555 +seed2 = 93463 +seed3 = 29345 +seed4 = 68237 + +check_seed(seed1) +lin_cong = linear_congruential(seed1) +check_data(lin_cong, "Uniform", paste("LCM Random Data with seed", seed1)) + +check_seed(seed2) +lin_cong2 = linear_congruential(seed2) +check_data(lin_cong2, "Uniform", paste("LCM Random Data with seed", seed2)) + +check_seed(seed3) +lin_cong3 = linear_congruential(seed3) +check_data(lin_cong3, "Uniform", paste("LCM Random Data with seed", seed3)) + +check_seed(seed4) +lin_cong4 = linear_congruential(seed4) +check_data(lin_cong4, "Uniform", paste("LCM Random Data with seed", seed4)) + +# Using the standard built-in R function +unif = runif(100, 0, 1) +check_data(unif, "Uniform", "R Random Uniform Data") + +# Building exponential from linear congruence method +exp1 = -log(1 - lin_cong) / 3 +check_data(exp1, "Exponential", "Exponential Data from LCM Random") + +# Building exponential from runif +exp2 = -log(1 - unif) / 3 +check_data(exp2, "Exponential", "Exponential Data from R Random Uniform") + +# Building exponential from rexp +exp3 = rexp(100, rate = 3) +check_data(exp3, "Exponential", "R Generated Exponential Data") +``` + diff --git a/content/notes/stat381/randomwalk.md b/content/notes/stat381/randomwalk.md new file mode 100644 index 0000000..6c78179 --- /dev/null +++ b/content/notes/stat381/randomwalk.md @@ -0,0 +1,551 @@ +# Random Walk + +## Introduction + +This lab features a random walk simulation that answers the following question: Given the radius of a circular room, how many random steps does it take to reach to reach the wall from the center? To explore this, we will look at the distribution of steps required and describe it in terms of a discrete probability distribution. Later on, we will look at the radius parameter and find relationships between it and the different summary statistics that we compute (mean, median, range, variance, skewness). + +The paper will start off with the methods used in this lab. The programming language R was used and a simulation was created to simulate a random walk according to the description above. It will also discuss the methods used to find the discrete probability distribution that best fits the data and how the relationship between the radii and the summary statistics were found using regression. + +After discussing the methods, the paper goes into the results. The discrete probability distribution of the data is revealed and the equations of the different summary statistics based on a regression of the radius is shared. + +## Methods + +### Obtaining the distribution of steps required + +The simulation written performs the following steps given the size of a room: + +1. Start off in the center of the room +2. Calculate a random angle $\theta$ +3. Step in the X direction by $cos(\theta)$ +4. Step in the Y direction by $sin(\theta)$ +5. Repeat steps 2-4 until the wall is reached + +The number of steps required is then recorded into a vector and the simulation is performed 999 more times. This gives us the distribution of steps required to reach the wall given the room size. + +### Computing summary statistics + +Given the distribution vector pertaining to the room size, we then find the following information: + +- Measures of Central Tendency: Mean & Median +- Measures of Variation: Variance & Range +- Skewness & Shape of Histogram + +For every room size selected, a total of three trials of 1000 simulations each is conducted. + +### Fitting the data to a distribution + +Since the simulation counts the steps required before reaching the walls of the room, it describes the process of a geometric distribution. To confirm the suspicion, the function `fitdistr` inside the package `MASS` was used to find the parameter (probability) of the geometric distribution to best fit the simulation data. In this case the simulation data used is of room size 100. + +The probability density histogram of the data is then shown with the overlay of the geometric distribution that best fit the data. + +Another more robust way to visually see the goodness of fit of the distribution is to use what is called a Quantile-Quantile Plot (Q-Q Plot), Using the quantiles from the theoretical distribution, we compare it to the quantiles of the simulated data and check to see that it follows the Q-Q line closely. + +### Finding relationships between the radii and the summary statistics + +From the simulations performed, vectors have been saved containing the summary statistics for the different room sizes. Vectors are then created from these vectors as columns inside a data frame. Having this data frame allows us to use `ggplot` to graph the data using scatter plots. + +`ggplot` was used as opposed to the conventional `base` package since it allows us to add layers to the graphs, which was used to show the geometric distribution on top of the density histogram in the previous section. `ggplot` is also aesthetically more pleasing as it decreases the margins and makes smart choices on the shadings of the axes on the graph. + +After plotting the data, regressions are then taken with respect to different polynomial degrees of radii and analyzed for best fit using the adjusted r squared value as a means for comparison. + +The adjusted r squared value is a good comparator since it tells us a proportion of how much the variation in the data is accounted for by the model. + +## Results + +The shape of the distribution matches the geometric distribution as shown in Figure IX & X. Figure IX shows how the probability density histogram nicely fits the overlay of the geometric distribution with the fitted parameters. The description of the problem closely matches the description of the geometric probability distribution and both distributions are skewed right. These observations increase our confidence that the distribution is a good fit. This can further be verified with the Q-Q Plot. + +The Q-Q Plot in Figure X shows how the theoretical quantiles compare with the quantiles from the distribution. Since the observed sample quantiles start off in one side of the Q-Q line and ends up on the other side at the end, we can say that the data is not skewed with respect to the theoretical distribution. This along with the fact that the sample quantiles closely fit the Q-Q line supports the proposition that the geometric distribution is a good fit for the steps required in the random walk. + +Regressions were then performed for each summary statistic and the models that had the lowest degree polynomial with respect to radii and with relatively small standard error were chosen. + +For the mean, quadratic regression was performed and it produces the following model +$$ +\mu(Steps) = -31.409 + 7.800(radii) + 0.837(radii^2) +$$ +With this model, the adjusted $r^2$ value is 99.938%, which tells us that 99.938% of the variation in means is accounted for by the quadratic regression above. It's fit to the observed values can be seen in Figure XI. + +For the median, quadratic regression was performed and produces the following model +$$ +\widetilde{Steps} = -19.525 + 5.096(radii) + 0.687(radii^2) +$$ +The model above has an adjusted $r^2$ value of 99.957% which tells us that 99.957% of the variation in medians is accounted for by the regression above. It's fit to the observed values can be seen in Figure XIII. + +For the range, the quadratic regression performed creates the following model +$$ +Range(Steps) = 63.873 - 9.073(radii) + 5.572(radii^2) +$$ +The model has an adjusted $r^2$ value of 99.278% which tells us that 99.278% of the variation in the ranges of steps is accounted for by the regression above. It's fit to the observed values can be seen in Figure XV. + +For the variance, the cubic regression performed creates the following model +$$ +\sigma^2(Steps) = -88471.866 + 32256.076(radii) - 2418.835(radii^2) + 61.650(radii^3) +$$ +The model has an adjusted $r^2$ value of 99.779% which tells us that 99.779% of the variation in the variations of steps is accounted for by the regression above. It's fit to the observed values can be seen in Figure XVII + +Looking at the scatter plot of radii vs skewness of steps shown in Figure XVIII, there appears to be no relationship between the radii and skewness of steps. What the scatter plot suggests that the skewness is uniformly distributed. + + + +## Conclusions + +In summation, the distribution of steps required to reach the end of the wall follow a geometric distribution. This was backed up using the probability density histogram and the Q-Q Plot. + +Most of the summary statistics follow a quadratic regression while the variation follows a cubic regression. Skewness are uniformly distributed across the different simulations. + +In other words, the mean, median, and range follow a function that is a second degree polynomial based on the size of the room ($r^2$) and the variation follows a function that is a third degree polynomial based on the size of the room $(r^3)$ + + + +## Appendix + +### Tables + +#### Table I, Summary Statistics for Room Radius of 2 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ----- | ------ | -------- | ------ | -------- | +| 1 | 5.827 | 5.000 | 13.471 | 36.000 | 2.446 | +| 2 | 5.761 | 5.000 | 10.635 | 22.000 | 1.780 | +| 3 | 5.805 | 5.000 | 11.430 | 21.000 | 1.882 | + + + +#### Table II, Summary Statistics for Room Radius of 3 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ------ | ------ | -------- | ------ | -------- | +| 1 | 11.566 | 9.000 | 59.055 | 60.000 | 1.854 | +| 2 | 11.940 | 10.000 | 74.487 | 68.000 | 2.467 | +| 3 | 11.242 | 9.000 | 53.417 | 48.000 | 1.922 | + + + +#### Table III, Summary Statistics for Room Radius of 4 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ------ | ------ | -------- | ------- | -------- | +| 1 | 19.306 | 15.000 | 171.688 | 90.000 | 1.721 | +| 2 | 18.127 | 15.000 | 143.284 | 74.000 | 1.712 | +| 3 | 18.993 | 15.000 | 180.892 | 111.000 | 2.089 | + + + +#### Table IV, Summary Statistics for Room Radius of 5 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ------ | ------ | -------- | ------- | -------- | +| 1 | 29.272 | 23.000 | 405.817 | 150.000 | 1.737 | +| 2 | 28.382 | 22.000 | 402.801 | 146.000 | 1.862 | +| 3 | 27.891 | 22.000 | 390.221 | 211.000 | 2.308 | + + + +#### Table V, Summary Statistics for Room Radius of 10 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ------- | ------ | -------- | ------- | -------- | +| 1 | 110.234 | 87.000 | 6070.976 | 547.000 | 1.780 | +| 2 | 109.594 | 88.000 | 5928.037 | 542.000 | 1.864 | +| 3 | 108.398 | 86.000 | 6469.467 | 621.000 | 2.191 | + + + +#### Table VI, Summary Statistics for Room Radius of 25 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | ------- | ------- | -------- | ----- | -------- | +| 1 | 623.260 | 492.000 | 197161.8 | 3262 | 1.965 | +| 2 | 637.890 | 511.000 | 212826.6 | 3394 | 2.009 | +| 3 | 653.661 | 528.5 | 211126.2 | 3694 | 1.841 | + + + +#### Table VII, Summary Statistics for Room Radius of 50 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | --------- | ------ | -------- | ----- | -------- | +| 1 | 2507.935 | 1939.0 | 3231980 | 11471 | 1.726 | +| 2 | 24675.615 | 1992.0 | 3248443 | 14150 | 2.060 | +| 3 | 2488.795 | 2001.5 | 3038915 | 14689 | 1.843 | + + + +#### Table VIII, Summary Statistics for Room Radius of 100 + +| Trial | Mean | Median | Variance | Range | Skewness | +| ----- | -------- | ------ | -------- | ----- | -------- | +| 1 | 8983.406 | 7257.0 | 38271895 | 52549 | 2.027 | +| 2 | 9372.917 | 7537.0 | 41658620 | 51810 | 1.867 | +| 3 | 8974.549 | 7294.5 | 41868765 | 60326 | 2.420 | + + + +### Figures + +#### Figure I, Histogram of Room Radius 2 + +![img](data:image/png;base64,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) + + + + + +#### Figure II, Histogram of Room Radius 3 + +![img](data:image/png;base64,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) + + + + + +#### Figure III, Histogram of Radius 4 + +![img](data:image/png;base64,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oDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQnoDgBpaWpgoDiBBQ3rgH98YzfN5aWXTB3xvzLX4isrEpAaWmqIKA4AcWNa0DnZw1AHz8wy2Zn2WHLVlsZkoDS0lRBQHECihvHgD5/UTYA6LHZ/L7KY4dlZ662MiQBpaWpgoDiBBQ3bgG9cd4nsgFAF2Yza1fM43tPfXLYytAElJamCgKKE1DcuAX06/vtt9/UBqAXZ2fUb4/Jrhu2MjQBpaWpgoDiBBQ3bgGttV8D0JOym+q3V2ULhq0MTUBpaaogoDgBxQlotSOzu+u3N2WnDFsZmoDS0lRBQHECihPQanOyh+u3t2Tzhq3U+/Y36/3tzBda6MJEAW3lz0Lr61s8lqdvsaeWdHoEkfr6nur0ECI9neZUpXhVLUlxqhb39Y1439IxAHRa9kT99t7soGEr9aZMrjdnZl8LnZcmoOu38mcxsy5v0RgAuv/gk84jhq3UE1Az643GAtDDs3vqtzdlXxy2Uu8nN9Y7ctbyFvpGmoBu0MqfhVZ9XTqWp2+xp5Z0egSR0pyqp1OcqsV9izs9hEhLum2qnhkDQE/Mbq7fXpOdO2xlaL6JREvznRHfRML5JhLON5GqXZqdU789Mbth2MrQBJSWpgoCihNQnIBWWzT1gOXVm2XTpz83bGVoAkpLUwUBxQkoTkBrHZedtqKyfH529morQxJQWpoqCChOQHECWmvR7GyfedOzg59ZbWVIAkpLUwUBxQkoTkD7H/GcOdPmXvR8ZGVVAkpLUwUBxQkoblwDumYJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6A4AcUJKC1NFQQUJ6C4XgX0rLOGrCw667I2jEpAaWmqIKA4AcX1KqBh6Oa7wzZtGJWA0tJUQUBxAoobD4Cu/FqY2IZRCSgtTRUEFCeguB4E9NYtqoWwxWCvCWH7NoxKQGlpqiCgOAHF9SCg/xNW7x/aMCoBpaWpgoDiBBTXg4A+cny1EI5f1Reua8eoBJSWpgoCihNQXA8C2r+1/Z9uElBamioIKE5Acb0K6CGHtHVEtQSUlqYKAooTUFyvAjoGCSgtTRUEFCeguB4G9IF/++Gq2jAqAaWlqYKA4gQU17OA/tf2TW/Dt2FUAkpLUwUBxQkorlcBfXBiENARE9BUSnOqBBTXq4AeGMLH//WX9w3WhlEJKC1NFQQUJ6C4XgV0p7BXW4dUEVBemioIKE5AcT0K6Mr1wg3tHZOA8tJUQUBxAorrUUCfDeF/2zsmAeWlqYKA4gQU16OAvrRxWNDeMQkoL00VBBQnoLgeBbQyN+z0bFvHJKC8NFUQUJyA4noV0GfeHab8sq2DElBcmioIKE5Acb0K6PXffXNY+8Nzjxv4QhsSWFQAACAASURBVKY2jEpAaWmqIKA4AcX1KqDDvxC0DaMSUFqaKggoTkBxvQroxsNqw6gElJamCgKKE1BcrwI6BgkoLU0VBBQnoDgBxQkoLU0VBBQnoDgBxfUUoOs/kN+jK/PPFC1NFQQUJ6C4XgX04WG1YVQ9BOgmkX93L9KUFgVNUwUBxQkorlcB9V340VqHARr68k8VK00VBBQnoDgBxfUUoGvtkdukEJ7IP1WsNFUQUJyA4noV0GsH+sb/2z6sdfrI5+P1FKDgTaRdBXTsS3OqBBTXq4AOafnRIVxafFACiktTBQHFCShuHABaWfkXYdOXCw9KQHFpqiCgOAHFjQdAK98O4c6iYxJQXpoqCChOQHHjAtA7Qni06JgElJemCgKKE1DcuAD02uDvwjcloKmU5lQJKG48APrKh8P7Co9JQHlpqiCgOAHF9SqgVw921ZmTQ5jXhlEJKC1NFQQUJ6C4XgW0+WP0W7Zj6gWUlqYKAooTUNx4AHTjj/2uHaMSUFqaKggoTkBxvQro40N6tT2jElBamioIKE5Acb0K6BgkoLQ0VRBQnIDiBBQnoLQ0VRBQnIDiehjQZy/YZ6etNn/bx89r09UgoLQ0VRBQnIDiehfQSycNvIk0qR1fJSKgvDRVEFCcgOJ6FtAza2+/v3fajPfXvn39nHaMSkBpaaogoDgBxfUqoAvXCa8949na0gtnbR7W/XUbRnXcrJUtdEk3A/p4K3/ilSurKrR24Ji25JlOjyBSmlO1NMWpqgLa6SFEWras0yOIVAV0xPuWM0APC+v9bGD5v9cLn8v3IrdjZ/a10HndDOjCVv7EZpZsixigO4ZDVq0cGnbK9yK342Ytb6FvdDOgj7TyJ16+vK/vqdYOHNOeWtLpEURKc6qeXtrpEURa3Le400OItCTFq2q0qXqGAbpRuGTVymV+G1Nz/gw0ldKcKn8GiuvVn4FuOBTQb4WN2jAqAaWlqYKA4gQU16uA7jD0JfxhBJXcBJSWpgoCihNQXK8CeliY+N8Dy/8zsS1vIgkoLU0VBBQnoLheBXThOmGLc16sLb147pZh3V+1YVQCSktTBQHFCSiuVwGtnFX7FaSd9913l9ovJJ3VjlEJKC1NFQQUJ6C4ngW0csmmA7/KueklI+yyZgkoLU0VBBQnoLjeBbSy7GvT37b5Fm+b/k9t+iMKKC1NFQQUJ6C4Hga03QkoLU0VBBQnoDgBxQkoLU0VBBQnoLgeBfTl/+q/vXGvE29v16gElJamCgKKE1BcTwJ625zNtu9fujqE8J4b2zMqAaWlqYKA4gQU14uAnrp2CEMADeHEtoxKQGlpqiCgOAHF9SCg51TJfPdX+pdX3nfBLtXV89sxKgGlpamCgOIEFNd7gC7aIGz07aEbLlk/bNyOq1RAaWmqIKA4AcX1HqBfWu1f8FgQwultGJWA0tJUQUBxAorrPUD3Dtu/3Lxl5fbhL9swqvEG6J+EcPyp+f109SPTVEFAcQKK6z1A3xlmDz/m8LBNG0Y13gB9XUCt8+hqR6apgoDiBBTXe4BuFL4w/JgziRe5jTdAN83Hs94vVjsyTRUEFCeguN4D9DXhH4cf8xW/kb45CujXr8xrVwEtVJpTJaC43gP0LeHI4cccGt7UhlGNQ0Dz30TaX0ALleZUCSiu9wDdZzVBXt0mTG3DqAQ0koAWK82pElBc7wF6SQhXNm85N4Rz2zAqAY0koMVKc6oEFNd7gL60XXht0xeI/HiDsMVzbRiVgEYS0GKlOVUCius9QCs/WCtsfPbgR0Ff+NJ6IVzejlEJaCQBLVaaUyWguB4EtLJg7RC2OOiM791+3/9cctCkECac3JZRCWgkAS1WmlMloLheBLTyk62Hfk5x0jXtGZWARhLQYqU5VQKK60lAKy+cu+MAn9uctLRNoxLQSAJarDSnSkBxvQlotd9ddspRR5x04X3tG5WARhLQYqU5VQKK61lA25+ARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBGEtBipTlVAooTUJyARhLQYqU5VQKKE1CcgEYS0GKlOVUCihNQnIBG+ngIH9xjeLvtttuwLUevyH+8sU5AcQKKE1CcgEbaMbB+mP94Y52A4gQUJ6A4AY30ZgjoVfmPN9YJKE5AcQKKE9BIVUD/+YG8PiOgIyWgOAHFCWisVAFd/U2k4R0voCMloDgBxQloLAEtloDiBBQnoDgBjSSgxRJQnIDiBDSWgBZLQHECihNQnIBGEtBiCShOQHECGktAiyWgOAHFCShOQCMJaLEEFCegOAGNJaDFElCcgOIEFCegkQS0WAKKE1CcgMYS0GIJKE5AcQKKE9BIAlosAcUJKE5AYwlosQQUJ6A4AcUJaCQBLZaA4gQUJ6CxBLRYAooTUJyA4gQ0koAWS0BxAooT0FgCWiwBxQkoTkBxAhpJQIsloDgBxQloLAEtloDiBBQnoDgBjSSgxRJQnIDiBDSWgBZLQHECihNQnIBGEtBiCShOQHECGktAiyWgOAHFCShOQCMJaLEEFCegOAGNJaDFElCcgOIEFCegkQS0WAKKE1CcgMYS0GIJKE5AcQKKE9BIAlosAcUJKE5AYwlosQQUJ6A4Aa31nazRo7W1ZRfMnTH/8heG7ySgkQS0WAKKE1Bc6YCeNRTQxw/MstlZdtjwmRHQSAJaLAHFCSiudEDnZ/e/WG9ldeXYbH5f5bHDsjOH7SSgkQS0WAKKE1Bc6YAemL04uLwwm1m7fB7fe+qTzTsJaCQBLZaA4gQUVzagL03df9XKxdkZ9dtjsuua9xLQSAJaLAHFCSiubEB/l81btXJSdlP99qpsQfNeAhpJQIsloDgBxZUN6C+yk6/+7IxDT3ugtnJkdnd9403ZKY27H3u03vxZK1romwJaA/S7rcxde3t6WadHEKkKaKeHEGlJilNVBbTTQ4i0dGmnRxCpCuiI970wBoBel2XZtDlZtvf3qytzsofrG28ZfFo6ZXK9OTP7Wug8Aa0B+o1W5s7M2tyiMQD0gmzmz1+pPHdhttevK5VpWT8b92YHNe4W0JETULNuaiwAffC2vvrt6dnJlcr+g89Aj2jcffSh9Q6eubSFFghoDdBLWpm79rb4qU6PIFJf3+JODyGSU4VbnOSg+vpGvO/JMfxVzruyuZXK4dk99ZWbsi823+ubSJF8E6lYvomE800kXKd+F/6JbNrKyonZzfWVa7Jzm+8V0EgCWiwBxQkormRAn7/u+v6Fe7PDq+Jl59RXTsxuaN5NQCMJaLEEFCeguJIBXTk7u62+cG72T5XKoqkHLK8uL5s+/bnm3QQ0koAWS0BxAoor+yX8FdnsOyqV5ZdNnbWkunZcdtqKyvL52dnD9hLQSAJaLAHFCSiubEBX/EOWzZo7NZt1a21t0exsn3nTs4OHX0QCGklAiyWgOAHFlf8m0s0nzJpx1PlLGw9/zpxpcy96fvg+AhpJQIsloDgBxfmN9LEEtFgCihNQnIDiBDSSgBZLQHECihPQWAJaLAHFCShOQHECGklAiyWgOAHFCWgsAS2WgOIEFCegOAGNJKDFElCcgOIENJaAFktAcQKKE1CcgEYS0GIJKE5AcQIaS0CLJaA4AcUJKE5AIwlosQQUJ6A4AY0loMUSUJyA4gQUJ6CRBLRYAooTUJyAxhLQYgkoTkBxAooT0EgCWiwBxQkoTkBjCWixBBQnoDgBxQloJAEtloDiBBQnoLEEtFgCihNQnIDiBDSSgBZLQHECihPQWF0N6LkP5DfGl6KA4gQUJ6A4AY2EAJ0TUBvdnj+oAgkoTkBxAooT0EgI0A8zQMMZ+YMqkIDiBBQnoDgBjUQBfeceee0Uwun5gyqQgOIEFCegOAGNRAG9MnenrwtoMgkoTkBxAhpJQIsloDgBxQloLAEtloDiBBQnoDgBjSSgxRJQnIDiBDSWgBZLQHECihNQnIBGEtBiCShOQHECGktAiyWgOAHFCShOQCMJaLEEFCegOAGNJaDFElCcgOIEFCegkQS0WAKKE1CcgMYS0GIJKE5AcQKKE9BIAlosAcUJKE5AYwlosQQUJ6A4AcUJaCQBLZaA4gQUJ6CxBLRYAooTUJyA4gQ0koAWS0BxAooT0FgCWiwBxQkoTkBxAhpJQIsloDgBxQloLAEtloDiBBQnoDgBjSSgxRJQnIDiBDSWgBZLQHECihNQnIBGEtBiCShOQHECGktAiyWgOAHFCShOQCMJaLEEFCegOAGNJaDFElCcgOIEFCegkQS0WAKKE1CcgMYS0GIJKE5AcQKKE9BIAlosAcUJKE5AYwlosQQUJ6A4AcUJaCQBLZaA4gQUJ6CxBLRYAooTUJyA4gQ0koAWS0BxAooT0FgCWiwBxQkoTkBxAhpJQIsloDgBxQloLAEtloDiBBQnoDgBjSSgxRJQnIDiBDSWgBZLQHECihNQnIBGEtBiCShOQHECGktAiyWgOAHFCShOQCMJaLEEFCegOAGNJaDFElCcgOIEFCegkQS0WAKKE1CcgMYS0GIJKE5AcQKKE9BIAlosAcUJKE5AYwlosQQUJ6A4AcUJaKT2AVqdg83fnN/Ov8ofeTwBxQkoTkBxAhqpfYDODayj80ceT0BxAooTUJyARmofoAdAQD+XP/J4AooTUJyA4gQ0UlsBzf8Z6I8EtIwEFCegOAGNJKDFElCcgOIENJaACmhJCShOQHECGklAiyWgOAHFCWgsARXQkhJQnIDiBDSSgBZLQHECihPQWAIqoCUloDgBxQloJAEtloDiBBQnoLEEVEBLSkBxAooT0EgCWiwBxQkoTkBjCaiAlpSA4gQUJ6CRBLRYAooTUJyAxhJQAS0pAcUJKE5AIwlosQQUJ6A4AY0loAJaUgKKE1CcgEYS0GIJKE5AcQIaS0AFtKQEFCegOAGNJKDFElCcgOIENJaACmhJCShOQHECGklAiyWgOAHFCWgsARXQkhJQnIDiBDSSgBZLQHECihPQWAIqoCUloDgBxQloJAEtloDiBBQnoLEEVEBLSkBxAooT0EgCWiwBxQkoTkBjCWhbAf37N5Peek6rD8cSUJyA4gQ0loC2E9BX1g6o17X6cCwBxQkoTkBjCWg7AV0ewtqb5bZWmNTqw7EEFCegOAGNJaBtBvTd+ce8XkCTSUBxAhpLQOuAfvrp/J6PHSugOAHFCShOQCOVDOi17AeX6307cqyA4gQUJ6A4AY1UMqCnMUDD3pFjBRQnoDgBxQlopJIBPTWE103O6x0hTI0cK6A4AcUJKE5AI5UPaP6bSL8S0IIJKE5AcQIaSUCLJaA4AcUJaCwBFdCSElCcgOIENJKAFktAcQKKE9BYAiqgJSWgOAHFCWgkAS2WgOIEFCegsQRUQEtKQHECijt25tIWWiCgHQD0ryL/JRY/NXTtCQjopq38R+f19S0e2wdoqeapSqQ0p+qpFKdqcV/fiPc9KaCjJqACWjgBxQkozpfwkRIF1JfwhfIlPM6X8DgBjSSgxRJQnIDiBDSWgApoSQkoTkBxAhpJQIsloDgBxQloLAEV0JISUJyA4gQ0koAWS0BxAooT0FgCKqAlJaA4AcUJaCQBLZaA4gQUJ6CxBFRAS0pAcQKKE9BIAlosAcUJKE5AYwmogJaUgOIEFCegkQS0WAKKE1CcgMYSUAjofSGsu9nqTZrUtCqgIyegOAHFCWikFAH9MfzH4wV0pAQUJ6A4AY2UIqD/Fn8GOiwBHTkBxQkoTkAjJQpo7GegzS0T0JETUJyA4gQ0koAWS0BxAooT0FgCKqAlJaA4AcUJaCQBLZaA4gQUJ6CxBFRAS0pAcQKKE9BIAlosAcUJKE5AYwmogJaUgOIEFCegkQS0WAKKE1CcgMYSUAEtKQHFCShOQCMJaLEEFCegOAGNJaACWlICihNQnIBGEtBiCShOQHECGktABbSkBBQnoDgBjSSgxRJQnIDiBDSWgApoSQkoTkBxAhpJQIsloDgBxQloLAEV0JISUJyA4gQ0koAWS0BxAooT0FgCKqAlJaA4AcUJaCQBLZaA4gQUJ6CxBFRAS0pAcQKKE9BIPQ7opLD25Pw+8NX8M42QgOIEFCegsQS0fEDXZv/C/Nov5p8qnoDiBBQnoLEEtHxA12KAhqX5p4onoDgBxQloLAHtBKCbPp3bZAEtIwHFCWgsAe0EoOBNpD8W0DISUJyAxhJQAS0pAcUJKE5AIwmogJaUgOIENJaACmhJCShOQHECGklABbSkBBQnoLEEVEBLSkBxAooT0EgCKqAlJaA4AY0loAJaUgKKE1CcgEYSUAEtKQHFCWgsARXQkhJQnIDiBDSSgApoSQkoTkBjCaiAlpSA4gQUJ6CRBFRAS0pAcQIaS0AFtKQEFCegOAGNJKACWlICihPQWAIqoCUloDgBxQloJAEV0JISUJyAxhJQAS0pAcUJKE5AIwmogJaUgOIENJaACmhJCShOQHECGklABbSkBBQnoLEEVEBLSkBxAooT0EgCKqAlJaA4AY0loAJaUgKKE1CcgEYSUAEtKQHFCWgsAU0U0J1CeM/k/I6KHSugOAHFCWgsAU0U0E0C6/7IsQKKE1CcgMYS0EQB3RgCemfkWAHFCShOQGMJaLqA5v8M9G8EtGACihPQWAIqoCUloDgBxQloJAGFgO7KXua/L4n/PwooTkBxAhpJQCGgb4I/KP2X/Mcb+wQUJ6A4AY0koBDQbUPY5s15TQrhuvzHG/sEFCegOAGNJKAc0NjPQJubJ6AjJ6A4AY0loAJaUgKKE1CcgEYSUAEtKQHFCWgsARXQkhJQnIDiBDSSgApoSQkoTkBjCaiAlpSA4gQUJ6CRBLTNgH7+yvz+N39MxRJQnIDiBDSSgLYT0I+xD9tPuCl/UIUSUJyA4gQ0koC2E9APwl9XOid/UIUSUJyA4gQ0koC2GdA5p+a1VwhfzR9UoQQUJ6A4AY0koG0G9Pu5O50roAkloDgBjSSgAlpSAooT0FgCKqC1BDSlBBQnoJEEVEBLSkBxAhpLQAW0loCmlIDiBDSSgApoSQkoTkBjCaiA1hLQlBJQnIBGElABLSkBxQloLAEV0FoCmlICihPQSAIqoCUloDgBjSWgAlpLQFNKQHECGklABbSkBBQnoLEEVEBrCWhKCShOQCMJqICWlIDiBDSWgApoLQFNKQHFCWgkAU0V0KVPg14Z4dgmQJ8jZ3oRDKlYAooT0FgCKqC1EKBL3oG+2n7D+L9h1wToTHSmtY7PHVPBBBQnoLEEVEBrIUD/Ff7jIPtGjx4K6HPwTG/MHVPBBBQnoLEEVEBrIUB/EMJWk/P6wxBmRI8eCmh1ojbKPdPktcNWuWMqmIDiBDSWgApoLQro0bk73QUB/WDumSqbCWhCCWgsARXQWlVA592a15kCWk4CihPQSAJaOqDz4Q8lBbSMBBQnoJEEtHRA/0ZAE0pAcQIaSUA7AeiHPp3XZAEtJwHFCWgkAe0EoPlvIp0goOUkoDgBjSSgAlprUtjk/Py+9Vj+mV65coSD//GMf1y1cvEd+WcqJQHFCWgkARXQWuuwn8v+Qf6ZjmFnWvc3+acqIwHFCWgkARXQWhPgO1v5vzK/NzzTD/MHVUYCunrLLpg7Y/7lLwzfLKCRBFRAa00IG5+a2xsgoEflnulDAjpanQX08QOzbHaWHTZ8ZgQ0koAKaK0J5E2k90BAF+budLiAjlZnAT02m99Xeeyw7Mxh2wU0koB2N6Bv/3ysI/5uyHLXArri3OgfbnhnvJQ/8utGPPqIIwYX9/vQZ8DDHXd//sM9dDwa+b+PdHxHAV2Yzaz9/fv43lOfbL5DQCMJaBcD+h/wx41dCui34R/vnNwz/XYteKo2zeZH2JkmjnTZdRTQi7Mz6rfHZMO+K1FAIwloFwP6vfb9Xz5FQM+Af7zjcs90CzwT6k25D1f5Q3iqB0c4vqOAnpTdVL+9KlvQfIeARhLQ7gZ01xvzuqKbAT0i9493AgT0z3LP9I0Q3pm7040TIaA/yj3TBxIF9Mjs7vrtTdkpzXcIaCQB7W5A428iDe3Rbgb0/NydroaAzs7daWEIH87dqbIhBPTV3J3+KlFA52QP129vyeY1thx9aL2DZy5toQUhvGWPvHYMYevcnap/42yeu9MeIWyUv9OEsFb+TutUn5/k7rRB9f9euTtNqv7dnLvTG0LYIXent4awbe5O7w1hy9yddg9h49ydqhO1Tv5Oa4ewe+5O64ewc+5Om1RVz91pqxB2zN2p+hfbdrk7vSuErXJ3+tMQNsndqXrZrZe/04bVK2r3vLYIYZfcM70xhHflnuktIeyUe6Z3Vicq90yTQ3h97pl2CWFS/hysFSbmPtzuG1Wf8eaeafPqX8kjoLO4r29EkJ4ca0CnZf3Pu+7NDmpsmdL/pdtzZva10Nfa+eMTM7OBbm8BpEVjDej+g89Aj2gHoLdv3ulZNrNe7H2Ppwjo4dk99dubsi82tjz2aL35s1a00rP3gxbeBXa67/9W33b7agfeTh4vcqYWd7pz4erbbr31tuYNd98LznTP3WCnX5KJWnhHbOvtdw5bB2dq50TdF9t6661Nw7j7l+BM99wDdvolmc2Fd8a3/9/Q7b9q3xygnX4Rnaj7779t6FV1F5moO8jFci+aqFtGfIxV1xqbKHTZ/Zzs9MjLI5nzVN/iET16YawBPTG7uX57TXZu8x2tvYk0xi15ttMjiNTX93SnhxBpyTP5+5RemlO1NMWp8uvscB19E+nSrP+DtSdmNzTfIaC0NFUQUJyA4gR0eIumHrC8erNs+vTnmu8QUFqaKggoTkBxArpax2Wnragsn5+dPXy7gMLSVEFAcQKKE9DVWjQ722fe9Ozg4ReRgNLSVEFAcQKKE9DIw58zZ9rci54fvllAaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKE5AaWmqIKA4AcUJKO64P5mdXjNndXoEkfbdd2anhxBpZoqDcqpw++67b6eHEKnrpmpWhwB95XtzJpuZdXsdAfT5yZP3ONlIJ02evHunx9AtfWDyrp0eQre08+QPdXoI3dKHJu882t3/1yFA9y/nkbq+VydPntHpMXRLO0+e2ukhdEu7Tf6LTg+hW/ro5N35zgKaWgLKE1CcgOIEtKsTUJ6A4gQUJ6BdnYDyBBQnoDgB7eoElCegOAHFpQjoC1OmHFzOI3V9r06Z8slOj6Fb+vMpKf56RpLtOWV6p4fQLX18SsZ3Lu2D9GZmvZaAmpm1mICambWYgJqZtZiAmpm1mICambVYOYAuu2DujPmXv1DKY3VrD535qY8f9KVf1pe/kzV6tMODSrLm2fHaGrn9ssF+7VU1Wj+e8fvGUtP1lH9xlQLo4wdm2ewsOyzFb09Npf/cO8vmTs+mXl5bOctLfZSaZsdra5SGAPqQV9Vozc8agDZdT+DiKgXQY7P5fZXHDsvOLOPBurOl07PTnqqs+OepU++s1P5z3v9ivZWdHleKNc2O19YovdjotuyLFa+qkXv+omwA0KbrCVxcZQC6MJtZ+0cOHt976pMlPFp3dlV21Ira7UXZydX/PTB7scPjSbmhs+O1BXr50Jm1f8/DqyrejfM+kQ0A2nQ9kYurDEAvzs6o3x6TXVfCo3Vnp2SX1W8XZp+sVF6a6hcHjFzT7HhtgS7L/qPiVTViX99vv/2mNgBtup7IxVUGoCdlN9Vvr8oWlPBo3dmXPnlr/fY32QGVyu+yeZ0dTdI1zY7XVn4P731i7carapT2awDadD2Ri6sMQI/M7q7f3pSdUsKjdXeXZ39fqfwiO/nqz8449LQHpZxU4wAABzRJREFUOj2aJGuaHa+t/I6d+mDtxqtqlAYAbbqeyMVVBqBzsofrt7f4V2Bed3w8u6tSuS7Lsmlzsmzv73d6PCnWNDteW7n9X3Za/darapQGAG26nsjFVQag07In6rf3ZgeV8Ghd3PJL9sq+U729IJv581cqz12Y7fXrTg8pwZpmx2srt7/b65H6rVfVKA0A2nQ9kYurDED3H4T8iBIerXv72SezGT+sLTx4W199w+n1t+StuabZ8drK6+fZqf0LXlWjNABo0/VELq4yAD08u6d+e1P902gWb9mpWfblJ5o23ZXN7dBguqH67Hht5XVCdkvzBq+qSAOANl1P5OIqA9ATs5vrt9dk55bwaF3aEwdmBy0cvi2b5meeR6w+O15bOT059YBXm7d4VUUaALTpeiIXVxmAXpqdU789MbuhhEfrzp4/JPvScwPL113fv3BvdnjHBpRszbPjtZXTt7OL+he8qkZrANCm64lcXGUAumjqAcurN8umT38ud9/x2vezvx98WrBydnZbfeHc7J86NqBka54dr62cDmu8DPWqGrUBQJuuJ3JxlfK78Mdlp62oLJ+fnV3Gg3Vnn8nufLVRpXJFNvuOSmX5ZVNnLen0uBKseXa8tkZtcbb3S41Fr6pRGgC0+XoCF1cpgC6ane0zb3p28DNlPFhXtmKvwa/N+XR17R+ybNbcqdmsWzs9rhRrnh2vrVH7cXbUwKJX1SgNAtp0PYGLq5zvA33qnDnT5l70fCmP1ZX9PhsKaKVy8wmzZhx1/tJODyvRmmbHa2u0/nHgR6C1vKpGbBDQ5usp/+LyG+nNzFpMQM3MWkxAzcxaTEDNzFpMQM3MWkxAzcxaTEDNzFpMQM3MWkxAzcxaTEDNzFpMQM3MWkxAzcxaTEDNzFpMQM3MWkxArWu69/N77rT+lu+a86+vdHokZv0JqHVJLx0yITR6/2/6Nz3yP345sHU0AbUuaVoIEw8866rzjt42hM1+V990fNiiw4OycZ6AWnd0ZQjvWlRfeukLIUypLwmodTgBte7or0N4aGD5EyHUX7sLqHU4AbXuaJuw4+Dy90I4v3Y7KqDPrhjzMdm4T0CtO3p92GZw+Yn582+uVA7pf0fprNqW507bZfON33XIffW7zw1/VLlkhzBhyz/75qv9Byz94m5bb/iO6T8rf9jW2wmodUcfDuGM5i1DAL1j2/7lCafU7qgC+oXG+/W7Latt+NlmjdUjSx+29XYCat3RxVX/PnLFs03bBl7C/7YK5D7nf3fepiGcWqkBusGE8P4vfeuIN4Tw0er6718XNvrbK75/ytYhXF/+wK2XE1Drjl7dr/YUct0/PfGnLw1uGwD0r8M619ZuH9oxbPDbGqAhzK192P6xySFcValcFMKNtbsfWC98qgMjtx5OQK1buuSP+1+Hb/iX33m5f0sD0IUhHNW/4cchHFcHdLv+Pe5fu/aBp8+F9Vb273/gl8oftvVyAmrd04MXztyqbuh2t9fXG4B+OYRHGnvsEHavA3pmY33fsGGlcnIIX3u1A8O13k9Arbu69+xd1wphg7tryw1Ap4etB+7dK2xVB/Q/G+tnh7Cocv9GIbzp//vZ8g6M1no8AbWu694/CWGP2kID0A+FIW1UB/TRxq4/qFt641tq90zc42vLOjZm680E1LqiWy67bNXKsu3CWi9WBgF9z1BAw6tDAf1hCP9WvVn+vQNfX7vvjf9R+sCtpxNQ64q+VHstPtghIfyyMgjo7mGXpn2rgP5s1eKDjcX7F0wOYYvFYz9UG0cJqHVFl4Vw9aq1qSE8URkE9KCw1crGHStWvFpX8+zG+gFhvRWVhx9+qn/t7BCuKW3ENh4SUOuKHp0Ydhh8F2jRJuEdtdsGoN8N4dr+O/pe0/gY0x/0f+fyA+uGP65Utg579t+9MIRvlDpq6/UE1Lqjz4Qwpf9bQCuPvDeEi2oLx4fX1J56vrx1eEP9t+BfysKE3/R/kP6Q2leJPL5zCJdUKllYv/6mfWV+/yt/s3YloNYdPVPFcL3dD/ryWZ//2Noh7FV/zf6FEBbcvahSuWFC2OCAr11/5ttDOLZSB3SDsPOp35m3dQi7VXe8LoSJn7v0Xy/8qxD+fGXOw5itSQJqXdLSTw3+kx5rfbb/1zmvG/gykcs3aNzxudrmKqD/smn/hj95urbh8wNH7ry0c+O3XkxArWu664Rdtp64xeSPf/E3A1tOetN6W9c/3vTIvHdu8pr3ffKe+tYqoM899rk3T3ztbhc2fgHp9v3e+9qN3znthg4M2no6AbWeqwZop8dg4yMBtZ5LQK2sBNR6LgG1shJQ67kE1MpKQK3nElArKwG1nuvaPfZ4sdNjsPGRgJqZtZiAmpm1mICambWYgJqZtZiAmpm1mICambWYgJqZtZiAmpm1mICambWYgJqZtZiAmpm1mICambWYgJqZtZiAmpm1mICambWYgJqZtdj/DxgL0SJBrTdyAAAAAElFTkSuQmCC) + + + + + +#### Figure IV, Histogram of Radius 5 + +![img](data:image/png;base64,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rR4CKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDECmgcBDURAxQioGAHNg4AGIqBiBFSMgOZBQAMRUDECKkZA8yCggQioGAEVI6B5ENBABFSMgIoR0DwIaCACKkZAxQhoHgQ0EAEVI6BiBDQPAhqIgIoRUDEC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) + + + + + +#### Figure V, Histogram of Radius 10 + +![img](data:image/png;base64,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) + + + + + +#### Figure VI, Histogram of Radius 25 + +![img](data:image/png;base64,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oBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQjoBIBtRHQQAioRkAlAioQUC8IqERANQIqEVAbAQ2EgGoEVCKgAgH1goBKBFQj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) + + + + + +#### Figure VII, Histogram of Radius 50 + +![img](data:image/png;base64,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) + + + + + +#### Figure VIII, Histogram of Radius 100 + +![img](data:image/png;base64,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oBUEVICA2iOgAQIaJ1FA133pg6MS+KeHCKgCAbVHQAMENE6igBavQSITCKgCAbVHQAMENE6igP48YUB7CKgCAbVHQAMENE7SgE7ta+duAipCQO0R0AABjZM0oF9su9GjBFSEgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGoeAElABAkpAWyKgBFSGgNojoAECGqcY0LP72rmNgA4lBNTe8AnomRNXp6OvUHilcc0vCGh0oUsmUUAPXr20sDSl/10yfcuynkGnCoXerKfQqd7lWc+gQ68U/5VK83grMwvo6RMKVuYS0OiYNAP6KbP/VUCuLcrwKfz6dBSfwq9rXPNrAhod7dyuo9rZJelT+PXFp/Ap/e+SWb4i6xl0qvjgKOspdKrvxaxn0KG1xafwaR5vNd8DbSnPAW3/ItIFfA90KOF7oPaGz/dACWgMApoeAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwSUgMoQUHsENEBA4xBQAipAQAloSwQ0YUD7fnhzAv8l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) + + + + + +#### Figure IX, Probability Density Histogram + +![img](data:image/png;base64,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bXpiL7nySz979qy8HPf391evay099thjlu1LK1JRLSTcVBt07969b9++VjPbt2+vNuUdM2aMbT7/9Kc/yQnb5+cVUVuJb9y40XL+li1b5ITa4Hnz5s2WC2zatElOqG19XRcQEPDOO+/Yzk9PT5c//JKSEsueTe1Tb07VrVvXzmKDBw+2PSWp1GBSuFbVuOv05MYDw101p312finl2rx5s+xPNCgoyOpFeumWW27p3bu3nFbf4rZPrYXsHwkVUW8yFhcXy9qvcePGspsMRVFsh0S5cuWKHLkwMDBw8ODBcqa79nZl96dwoUaqOud9AFUWAXxNkZOTYxsSXL582XKZjh07/vTTT+rdXys9e/a0bLil2rhxo6IoQoi0tDT1esVKXFzc//3f/8lp9QLUijrskC31iv/IkSOWeX733Xd//fXXX3/9Vb0atuLIQC9OpOs16ol8yZIlcier1Cd1jzzyiBdyot7TUSf2798vm/ImJCRU1AugEGLgwIFyoqJyv/3229U3Aqw0atTIdqb6Wu/u3bt//vln2wWGDRv21ltvvfXWW7JVquuqTik4zhN7yZVf+po1a2R/y/fee2+5xarX65966qkb5qGiWki4qTZQ+4ezUr9+fTnRvXt3208dufVgpUuXLnJc9EOHDllevssAvlmzZvfcc48MDi1fxC0uLpZPff38/NSHja674447EhMTy/3Iia9mNBrlhMlksrPYpUuX7NyuOnPmjLqkK1WNu05Pbjww3FVz2mfnl1KuVatWyYkhQ4ZU1PPluHHj5F0/B48Kq9qysizvLZaUlMgJdbd8//33Vst/99138vWE++67T23x7q69Xdn9KVyokbR4xgHgZQTwNZ1er7/pppv69+//xRdfbN26tVWrVhUtWdEVnjqYSvv27e0k1KFDB6vlrZTbha/Utm1b9dypvixgh9Fo3LJly+uvv+7IuDVuTNftbr75Ztnf7Llz5ywfelg+KHj44Ye9kJP8/Hw5oT7BUIdH6tatm50V1SPq999/L3cBta27LcsehlQtWrSQnQmVlJT07Nlz8ODBixYtcvzxoBM8XQqVbQPvCE/sJVd+6erL2JatdazY+UhVUS1kR6Vqg4oiE/VQbNq0qZ1PHRcQEKB2n6nGDLm5uRkZGUKIbt26BQQEdOnSRQhx8eJFtRfJ7du3y0imffv2zj3VLJed36CdDrQr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5p1I1/s6d+4sn//v3bv30KFDcqTi2rVr245L7HalpaVPP/20vM6Ii4vr06eP+lGnTp1q1aolhNi0aZOda75Ro0YlJycnJyc7N5qxrccee6xevXr16tWbOXNmuQv07NlTZqysrMyJhpcV8WEpOMETe8mVX7o6gNOyZcvkOMZWTCbTZ5995kg2yuWu2sDLevToIUcm37Bhg9oA3vL5p2UzeLnP3TuAnIdERUU988wzcnru3LnlhuVWSktLBw0aVG6LZVeqGnedntzIVzWnfeoYezNnzqyo3fiiRYvOnTt37ty55s2bO7jZtLQ09azx+uuvL1my5IarXL16tX///vLWeURExJtvvmm7TL9+/eQgc8uXLy8tLZXvz+v1etu+2X21t12vkbR1xgHgZQTwcFVKSop60TN+/Hh1vFaV2Wx+8cUXZSdwMTExFZ1+tmzZsnjxYtv533//vTp/xIgR6ny1z+qK3o3cs2fPRx99dMP8VzZdT7DfR5FOp1N32hNPPCHv699///3u7XrKVmFh4cCBA9Wr3ilTplgOzBscHPznP/9ZzVW5nfxt2rRpzpw5QgiDwTBo0CC35Ept/VvRldbOnTtlq0uDwVCvXj3Ht1w1S8E5ru8l273hyi+9bdu2ciTtsrKych/Eff311851VS25qzbwslq1avXo0UMIcfLkyblz5wohIiMjU1NT1QVkM3ghxPr167du3SqESE9Pd+I1bxdH5HbCW2+9pb7MPHr06LFjx9rpB/TixYu9e/det25duZ+6UtW46/TkRu6qOd1bpn369JHhYn5+/quvvmq7QEZGxjfffCOnK/WO/RdffCF7tjeZTA8++ODkyZNlL27l2rt3b+fOneULETqd7uOPPy73aI+MjJRD2eXl5X399dfyp3HnnXfavlvuq/OU6zWSts44ALyMAB5u8M4778h7zNu2bbvzzjst35I9c+bMXXfdNXv2bPnvxIkT7TzKHjJkyLRp09Tb/9nZ2X/729/69+8vr1R69Ohh+QRYfTVu1apVX331leV2ioqKXn311S5duqh9px8/ftxO/iuVrifk5eXJ1q0VUfuklVcqwsPv0Z05c2batGk33XSTOobNwIEDH3roIavFXnnllfDwcCHErl27Onfu/Msvv6gflZaWzpw5895775U9Az/++OORkZFuyZscHFsIsXHjxoceekgdakgIYTabf/jhB/Wip1+/fpXq4r6qlYIrXN9L5e4NV37pH3zwgewd+rPPPnvxxRfVn1txcfHnn38+YsQIdXknejp0Y23gZepb9IcPHxZCdO3a1bK7LL1eL298nD59Wt5wce79+Rse225nMBgWLVqkhjF///vfmzRp8sYbb+zZs0fWCUKIsrKyrVu3jhkzJiUlRXbF//rrr7du3dp2a65UNdjTD44AACAASURBVO46PbmRW2pO95ZpQECAemft008/HTBggOXL5Bs3buzTp49MrkOHDpVqUFa3bt3vv/9exuEmk+nFF19s2bLl1KlTMzMz1XsQ+fn5S5cuHTRoUFpamjoS+9SpU4cMGVLRZtW36J9//nm5Havu61Q+OU+5pUbS0BkHgLeVOxArqo20tDRZ0BWNA39Do0aNklv46quv7Cw2efJky+OqTp063bt3txrYeciQIVZrqS/TqgPGCiF0Ol1qamrTpk0t123QoMHJkyetVrcMKVu0aDFkyJBHH320Q4cO6i3qwYMHq9scMGDA9OnT3ZKuepN+3bp1lvOHDx8u58+bN8+R5RVFkRcWQoiOHTuOHDlSdlprq6yszKpLMKPRaKc47FOHtK1bt27j/9WgQQP5Tq+lfv36VZTckiVLLB/LN2zY8NZbb+3YsaNlv4C33Xab7eovvPCC/FQtFFsdO3aUyxw/ftxyvvq2pyy1hISEHj16dOzY0bI0Y2Njz507Z7lWlSoFy7fWf/vtN0dWUY+uQYMGOfK9nNtLyo32hnO/dMnyVWqdTteiRYu0tDT1+JkxY4acSExMtFrRkVrI6dpAceBovOmmm+QCtrtLURT1+rtNmzYVZa8iMm5XTZ482WoBqzY+O3bssN2Ic8e2+q3t7NWWLVvKZS5dulTZr6YoytmzZ9UtqPz8/KKjo6Ojoy27NAsMDPzss88URXn22WeFECEhIVabcrqqUVw4aD13YLjydeyUqSO/FDtHy7Bhwyz3SePGjXv27Gk5Mnx4ePiBAwcq2rIdmZmZti/e6/X6uLi4sLAwq/m1a9f+/PPP7W8wLy/P8m5LnTp1iouLK1rY6b3tyP6s6LzvSo0kufe8D6A6IYCv5rwWwCuKMnPmTNszsRQQEPDyyy+bTCarVdRA+qWXXvr0009DQ0PLXT09Pf3EiRO2Kebm5qpPGq3Uq1dvwYIFiqIkJiaqM1u2bOmWdN0YwKtv90kREREV7V5140KIkSNHVlgMDlAD+BsKCwubOnVqWVmZna2tWbPG6lJY5e/vP2zYsLy8PNu1XAngc3Nz5fuTFbnjjjuOHTtmtbUqVQpeCOCd20uKA3vDiV+66uOPP7Z9yKnX6//xj39kZmbKf1NTU63WcqQWcro2UHwawCuK0qhRIzVX27dvt/p027Zt6qdRUVHl7lvnjm0vBPCKohQXF0+aNKmiOla67bbb5AByiqIsXLhQlBfAK85WNZJzB61HDwynv46dMnUxgDebzRMmTLCMdS0lJibu2rWros3eUHFx8Ycffmh/QHU/P78+ffqoB4N9DzzwgLriiBEj7C/s3N52JYB3pUay3bhw+bwPoDphGDm4zeOPP96nT5+ZM2f+8MMPx44dy87ODgsLa9SoUe/evYcNG5acnGxnXZ1ON3LkyAcffHDmzJnLly/PzMzMy8uLjY1t27btoEGDBg4cWO7wM+Hh4T///PP8+fO//fbbo0ePnjp1KiwsLDU19YEHHhg+fLi8z71o0aJRo0bt27evTp066u0MF9N1o08//TQqKuq77767ePFinTp1rJ7/W+rfv7/aIZlH36MLDg6Oi4tr2rTpAw880K9fP/vXW0KI22+//ejRo7Nnz162bNmBAwf++OOPqKiopk2bpqamPvvss82aNXN7DsPDw9esWfPjjz8uXLgwMzPz9OnTly5dqlevXmJiYkpKypNPPmlb0PZVwVJwndN76YZ7w5Vf+qhRo26//fYpU6asWrXq4sWL0dHRXbt2HTduXLt27dTxICzfEajU93WxNvCVO++88/PPPxdC1K5d27YX9LS0tJCQkMLCQuHUAHKOH9seYjAYXn755REjRqxcuXLp0qWHDh26ePFiYWFhTExM/fr1e/XqNWDAAMuhv+6444558+bJ1hZWXKlqXDloPcTpr+O5MtXpdG+//fbQoUO/+OKLVatWnT17trCwsG7dum3btu3bt+///d//udLEwGAwjB079umnn167du3KlSv37NmTlZX1xx9/BAUFRUVFNW/evEePHv369UtKSnJwg4MGDVJ7xavo/XmVT85TrtdIGjrjAPAmneL1vm0AOGHbtm2dO3cWQjRu3PjEiROWDWXhNZSC5yxdulQ+Uhs+fPg///lPX2cHAHyMMw6AcvEEHtCGr7/+Wk488sgjnMV9hVJwTkFBwZNPPimE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3JCYmDhjxoy1a9caDAZ14wQAAN6LLvQAALSbwMDQQYOm5udPOXVq31dfffTtt9scDquIVFdXL1u2bNmyZVqt9oorrhg6dOjVV1+dn5+fkZGhdsgAAMBrkMADANDONBpNZubgzMzBVqv522+3Hjr095Mn97lcDhFxOBx79+7du3evUjMqKqpv3749e/a87LLLMjMzu3fvnpaWlpCQoNXyAQ0AAJri+wEAAJ4SFKTr339C//4TLJbaoqKdRUVfnDix22yubKxgMBi++OKLL7744vytNBpNXFxcXFxcTExMdHR0REREZGRkRESEsqy8jIyMVNbGxsYGBQV1+JEBAAAVkMADADqduro6ZWHFihV+fh4frkWr1Y4dO/byyy/3XBPBweF9+97Yt++NIlJTc7qk5OuyskNlZYcrK09YreYmld1ud2VlZWVl5cX2dBERERHJycmJiYmpqandu3fv3r17jx49evbs6enZ/gAAQAcjgQcAdDrV1dXKgs1m65gWDxw44NEE/nwxMekxMel5ebcoL43Gsurq4pqaEoOh1GQqN5nO1dVVm83VFouphTs0mUwmk+no0aNNyqOionJycgYOHDho0KDBgwf36tWrA34NAQAAnkMCDwDovMLDwz36NLjL5TIajcqC51ppXmRkcmRkclbW1U3KXS6nxWJqaDBarWaLpdZiqbVa66xWs/LSaq21WGobGox1dfr6+pq6Or2Iu8keDAbDvn379u3bt3jxYhGJiooaNmzYyJEjx4wZk5ub20GHBwAA2g8JPACg87r99tvT0tI8t//a2tqXXnrJc/u/FH5+/qGh0aGh0S2p7HI56upqDIZSo/GsXn+mpuZ0VdXJJv3zDQbDxo0bN27cKCIpKSljx4695ZZbRo8ezSP0AAB4CxJ4AAC8np+fNjw8ITw8IS1tQGOh2+0uLz+h158sLz9SUlJQWvqN3W5RVpWWli5ZsmTJkiWRkZE333zz1KlTr732Woa+BwCgk+OjGgAAnxUZmZyQkNm79xgRcbkcpaWFJ07sPnFiV2lpodvtEhGj0bhixYoVK1YkJCTccccd99xzT15entpRAwCAi2MwGwAAugQ/P21a2oCRI++fOXPlo4/+c9y4BTk5I7XaH/rPV1RUvPLKK/379x88ePB7771nsVjUjRYAAFyIBB4AgC4nNDS6f//xU6e+8eij/xw//vdZ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ADzl+++/v+uuu9SOot04HA4R0Wg0/v7+aseCVnO5XG63m3PnjVwul8vlEhF/f3+NRqN2OGg1h8PBufNSfPB5NafTKSKcO2/EB59Xc7vdTqfTi86d8sfWKiTwPstisXz77bdqRwEAAAAAaB8k8L5p4MCBAQEBakfRbtxu97p160QkIiJi9OjRaocDdCGFhYXfffediFx99dVJSUlqhwN0FVardfPmzSISFxc3fPhwtcMBupCDBw+eOnVKREaMGBEbG6t2OOgqMjIyWlhT43a7PRkJ0A6cTufgwYNFJDs7e/Xq1WqHA3Qhr7766vLly0Xk5ZdfHjZsmNrhAF2FXq8fM2aMiAwYMODtt99WOxygC3n++efXr18vIu+++25eXp7a4QBNMYgdAAAAAABegAQeAAAAAAAvQAIPAAAAAIAXIIEHAAAAAMALMAo9vENERISIhIWFqR0I0LUEBQUpV59Wy+cF0HE0Go1y6YWGhqodC9C1BAcHK1efv7+/2rEAF8Eo9AAAAAAAeAG60AMAAAAA4AVI4AEAAAAA8AIk8AAAAAAAeAESeAAAAAAAvAAJPAAAAAAAXoBpgdDZmUym1atX792712QyZWdn5+bmTpgwISQkRO24gE7n1KlTH3/8cWFhocFgiI2NTU9PnzhxYq9evZpUa+E1pUo1wAecOnXqkUce6d279/PPP99kFVcf0O527Njxf//3f6dOnQoKCsrMzJwyZcrll1/epA6XHnwJ08ihUzt37tzjjz9eXV0tIpGRkUajUUTS0tJeeOEFZYpOAIovvvhi0aJFTqdTRBISEgwGg81m02g0kydPvuOOOxqrtfCaUqUa4ANsNtsjjzxSXFycl5fXJIHn6gPal9Pp/MMf/rB7924RCQ8Pt9vtFotFo9E89NBDP//5zxurcenBx9CFHp3aa6+9Vl1d3adPn6VLly5fvnzx4sVpaWklJSVLly5VOzSgEzEaja+88orT6Rw2bNiyZcveeeed1atX33vvvSKyevXqb775prFmC68pVaoBPuD9998vLi6+6CquPqB9LV++fPfu3QkJCS+99NKKFStWr1593333ud3uxYsXV1VVNVbj0oOPIYFH53X06NHCwkKdTvfEE0/ExcWJSHJy8jPPPOPv779jx47Kykq1AwQ6i61bt9pstpycnPnz58fExIiIv7//+PHjx40b53a7N23a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) + + + + + +#### Figure X, QQ-Plot of Theoretical vs Sample Data + +![img](data:image/png;base64,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) + + + + + +#### Figure XI, Scatterplot of Radii vs Mean Steps + +![img](data:image/png;base64,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) + + + + + +#### Figure XII, Scatterplot with Quadratic Regression of Radii vs Mean Steps + +![img](data:image/png;base64,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lVfeeuutZjsBAKB3IsADAIBL8r//+78Oh0NE7rnnnqblzz33nBa8s7Ky7rvvvoEDB6qqeuTIkddee+3IkSNffPHFokWLfv7zn/vr33333Vp6j4mJufXWWydMmFBcXPzZZ59t2rTptttu83q9Xfu2AAAIOgR4AABwMWpra0+dOvXOO+88//zzIpKbm7tgwYKmFV588UURGTJkyPbt2202m7/8gQceGDly5IkTJ9auXesP8H//+9+1GewHDx786aefDhw4UCtfuHDhww8//Oc//7lr3hQAAMGMe+ABAEA7fvGLXyjniYyMHD58+O9//3un0/mzn/3s888/N5vN/k2cTqfP5+vXr9+//uu/Nk3vIhIZGTl9+nQRKSws9Bf+5S9/0f544403/OldRHQ63QsvvDB06NBOfYMAAIQERuABAMAlMZlMiYmJRqOxWeGpU6da26SsrKxZyY4dO0TkyiuvnDBhQrOnFEX5+c9/ft9993VQewEACFUEeAAA0I558+bNmjWrWaHL5SosLFy6dGlRUdGvf/3rgwcPtj3V3Llz5woKCrZt27Zy5cqVK1c2faq2trakpEREJk2a1OK2U6dOvbR3AABAT0CABwAA7Zg0adL999/f4lP/8R//ceWVV+7YsePdd9997LHHhg8f3vTZgwcPvvbaa6tXrz5y5Ig20V2LCgoKtD8yMjJarKCtMw8AQC9HgAcAABfPZrM98cQTs2fPFpHVq1c3DfDPPPPMY489ps0ebzQax4wZk52dnZWVNXHixCVLlrz22mv+miaTSftDUZQWX8VsNkdERNTX13fiOwEAIOgR4AEAwCUZPXq09od2Gbzm66+/XrhwoYhoE91dddVV/pQuIh9//HHTPWRkZCiKoqpq02ntmiorKyO9AwBAgAcAAJckOTlZ+6Oqqspf+Prrr4tIeHj4119/nZiY2GwTj8fT9KHZbE5JSTlz5sy2bdtafIk9e/Z0YIMBAAhRLCMHAAAuiaqq2h9N55YvLi4WkYyMjPPTu6qqO3fubFaoTT6/cuVKbTr6Zp555pkObDAAACGKAA8AADpG00votbXcCwsLS0tLm9ZpbGz82c9+po2oa7fHax544AHtjx/+8IfNLqR/5plnVq1a1XnNBgAgVBDgAQDAJTEYDJGRkSJy9uxZf+E111wjIg0NDTNmzHjvvff27du3du3aRYsWDRs27C9/+YvFYhGRw4cPf/nll7W1tSIya9as+fPni0h+fv748eMffvjhd95554UXXrj66qsXLlxoMpmys7O75+0BABA0uAceAABcqrS0tH379h07dmzPnj2jRo0SkTlz5tx7772vvvpqXl7erbfe6q+p0+keffTRcePG3XzzzT6f73vf+96cOXO0Oe1ef/11h8Px6aefVlRUvPDCC/5NzGbzW2+9tXTp0vz8/K5/awAABA9G4AEAwKWaNWuWiKiqqo2iaxYvXvzxx/+/vTu0YRAAwjCaGsCRIDCEsAwGDRqDYBZWwVSwBoKR6rpC+yfvbXDyyyV373Ec+74vy3IYhm3bnuc5jmOe533f67pumub7+72qquu6zvOcpqlt26Iouq5b1/W+72VZfjMYAPyT1/fwDAAAAPC3bOABAAAggIAHAACAAAIeAAAAAgh4AAAACCDgAQAAIICABwAAgAACHgAAAAIIeAAAAAgg4AEAACCAgAcAAIAAAh4AAAACCHgAAAAIIOABAAAggIAHAACAAB8Jyj7k8GLIcgAAAABJRU5ErkJggg==) + + + + + +#### Figure XIII, Scatterplot of Radii vs Median Steps + +![img](data:image/png;base64,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) + + + + + +#### Figure XIV, Scatterplot with Quadratic Regression of Radii vs Median Steps + +![img](data:image/png;base64,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bt3a29tb/tLT0/ODDz6Ql5cuXVrwde0HJ/fs2VOSegllZmZ6eXnZ+wkODjYYDLcbXPDEafmWe506dWrXrp18w21ZjRo1EhISSt6APdB269at8KPyWfR2W7duVQz47rvv5IfatWtX+KGCab927dpdunRp166dPKe9/UVNJpNiRWdsprLsNjNnzpQfKlhUaNeunTzm4sWLt/9hF8FsNsfExIh/ko9Lh4aGFp77ferUqYWfRI7o8laYNGmSPN++Xek2REJCgvxQrVq1GjVqZP/hREdH33vvvQUbCwgIOH78uKIlZ+yrAAAAqGwI8Kq52wA/e/Zsebxerz969Ki9npGRYT++pxAWFrZx40ZJkqKiouzFpk2bFnzarKysQYMGFbl6cHBwXFyc/QZd5RPgJUkaMGCAvYeJEycWMzIjI0M+5f52evToceHChbt69eIDvP0cbyFEYGCg0WhUDCgmwEuStHv3bvvp6wp6vX706NGZmZlFduXwzVSW3capAV6SJKvVunLlyoLJtkjh4eHr168v8hns58nLgoKCFANKsSHsAT46OjoxMVHxkYpd/fr1C6d3yTn7KgAAACobbiOnGX369JkzZ44Qwmq1Dhs27PLly3I9MDDw4MGDX3755fr168+fP3/16tWAgIDGjRsPGDBgzJgx8gHVr776avLkyadOnQoODrbPai6rUqXK119/vW/fvs8///zgwYM3btxwd3ePjIyMiYmZOHFiREREMXN9OcnQoUPtMfh258/LAgMDd+/evWPHjk2bNl26dOnvv/++efNmWFhYVFRUgwYNxo0bp/hmy27IkCGvvfaavBwTE3O3Zzt37979/Pnza9asiYuL++OPP5KTk0NDQxs2bNi4ceMpU6bce++9t1vR4ZupjLuNU7m5uY0bN+7JJ5/cvXv39u3bf/311+Tk5JSUFDc3t8DAwKioqJYtW/bp06dHjx63u3Bg2bJloaGh33zzTWJiYnBwcMOGDRUDSr0hZGFhYQcPHly3bt369et///33tLS0qlWrNmnS5LHHHhs1alTBU0jsyn9fBQAAQMWjk+401TMA4Pr16/JB++joaHkGBAAAAKCcMYkdAAAAAAAaQIAHAAAAAEADCPAAAAAAAGgAAR4AAAAAAA0gwAMAAAAAoAHcRg4A7kyv19etW1cIER4ernYvAAAAqKS4jRwAAAAAABrAKfQA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bNiwYUKI2NhYNXp0DAI8AAAAAECrzpw5u3xHrTxrVUW9a9Nbb0xu/uuvv168eHHUqFEpKSn/+te/goKCDh48aDKZVGm17AjwAAAAAABNOnv27H8P1vj9qr+i3rBW3mNtE6KiooQQ9erVW7169ccff2yxWHJycqxWa1JSkhrNOgABHgAAAACgSYfPBe44EaIohgaYn380oWGDqOYE7D4AACAASURBVILFsWPHjh071mKxCCF8fHzKr0WHIsADAAAAALRn509XPtkTpih6uktT+ya0bdWw8PipU6cKIfR6fdWqyvPttYIADwAAAADQmJ9/vbBoc4TJooi00tjuN/p0jipyle3btwshrFZrTk6O8xt0CgI8AAAAAEBLTp85t2R7eFqOh6LumfaFr/FgkaucOHHizTff1Ol0Qoi0tDSnt+gcBHgAAAAAgGacPXt27Q81ziX4Kur63GMet1Y988wzixcvNpvN9rokSZ9//nmXLl3y8vKCg4OFEKGhoeXaseO4q90AAAAAAAAl9dOZwH1/BCuK3rpbuoR/t2hx/9Gjh2fMmDFv3ryOHTuGhYWlpqYePnz4ypUrOp1u8uTJS5cubdy4sZ+f8o7xWsEReAAAAACANsTtu/rZvpqKorenbXDzowd/3PHzzz///PPP/fr1S0lJ2bhx44cffrh+/fqrV68+/PDD+/fvv3XrlhDiySefVKNxx+AIPAAAAABAA44cv7BkW5TZqitY1OnEuO43nnr00XWxrY4ePfrRRx99++23GRkZ+/fvT0lJCQwM7NixY61atd55552NGzeGh4c///zzavVfdgR4AAAAAICrO/XHuUVxddJzlBl2ULvkNg2y3dzcNm3a1LZt248//vj06dNvvvlmp06dhBCSJF2+fHn8+PFbt2719fX9+uuv/f391WjfMQjwAAAAAACXdvbs2U/21LqS5KOot6mfHfNASqNGjYQQUVFRR48eHTx48OHDh7t37+7j41OtWrW0tDT5pnFRUVGbNm1q1aqVCt07DtfAAwAAAABc2tbjVQ+fC1QUa4UYx/a40bhxI3vlnnvuOX78+Oeff96zZ08vL69r165JktSxY8elS5eePXtW6+ldcAQeAAAAAODK/rsjftPhSEXRz9v6QkxCy/vvVdTd3Nyeeuqpp556Kj093WQy6fV67d40rjCOwAMAAAAAXNS+w5eW76hl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LZfL5fF4+ID8lsfj8Qb4oKAgfhHmt5qamgwGA+eR32odgeK3n9F5/HqOAO+TyMhIaW+su3f6uo4CfED4wQ9+8Oyzz27atOmRRx556KGHvBtnZ1szk22ZoxLcdsuNq5bbGstdtiqdNO/atWvixIltD3/22WefeOhu7+VKm0UiwsOee+65G264wbt348aN1113nXcGgZSUlNOnT588eTIpKclsNsfHx9tstvLycu9vHIKCgg4cOECmBQAAAICOaLtuApFRo0aJSF5e3lnbvVvS0tLaOSZArF69esSIESLy8MMPZ2dnHz58WERWXT78jm9GrXvhO8vnx9aVbHVYCz3OeofDMWnSpJSUlFtvvfU3v/nNypUrzWbzXXfdpapqSEjIAw88ICLNzc033nijVqs1GAxarXbJkiXe9H7NNdecOnXqxRdf9N6qV19ff+zYsTNnznjT+5QpU+rq6jIzMwfyHwIAAAAA/BtX4H2yaNGif/7zn7t377bb7a1Xia1W66FDh4KCgubNmzew5fVQcXHx2LFjjxw5oijKuHHjNBqNVqttXQRIr9d/9tlnkZGRM2fOtFqtZ86ceemll9oePnbs2Ly8vKCgoNtvv33x4sUnTpxQVbV17ZPExMR169bNmjVLRG655ZZbbrll+/btf/jDH06ePBkRETF79uyf/vSnDMADAAAAgC5xBd4nSUlJOTk5tbW1q1ev9iZbu93+6KOPOhyOuXPn+u2kCL4rKCj461//ajabRURVVe97NBgMl112WUtLy6xZs7Kzs+vr6//+979nZWVFREQEBwdHRkbOnTv3q6++UhTFOzQrPT39+PHjHo/n6NGjb7zxxp49e1RVLSsr86b3VhdddNHbb7+9d+/e3Nzc3/72t6R3AAAAAPAFV+B9dccddzzwwANbt27du3dvampqUVGRw+FITk6++eabB7q03nHrrbfeeuutIrJ3797Kyso5c+Z4V7lva9WqVatWreryqUaPHj169Og+qRIAAAAAhioCvK+SkpKeeeYZ74XlwsLC6OjoWbNmXXPNNd6l4AeTKVOmDHQJAAAAAICzEeC7ITo6+s477xzoKgAAAAAAQxFj4AEAAAAACAAEeAAAAAAAAgABHgAAAACAAECABwAAAAAgABDgAQAAAAAIAAR4AAAAAAACAAEeAAAAAIAAQIAHAAAAACAAEOABAAAAAAgA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HgAAAACAAECABwAAAAAgABDgAQAAAAAIAAR4AAAAAAACAAEeAAAAAIAAQIAHAAAAACAAEOABAAAAAAgABHgAAAAAAAIAAR4AAAAAgABAgAcAAAAAIAAQ4AEAQPs2bNig6Zher09LS1u0aNHDDz9ssVj6upi4uDiNRvOzn/3M+9eamhpvGS+99FJrm3Y3AgAwaBDgAQDA+XC73cXFxZ9++ukjjzwyatSo1157baArAgBgkNMPdAEAAMDfrVy5cvHixWdtbGhoOH369Lp160pKSurq6m6++ebMzMwZM2YMSIUAAAwFBHgAANCFmTNn3n777e3u+t///d8VK1Zs2LDB7XY/+eSTa9as6Z+SoqOjy8vLRcRkMnW+EQCAQYMADwAAzl9ISMhLL72UkpKiqur+/fv77XU1Gk1CQoIvGwEAGDQYAw8AAHpk2LBhqampIlJYWGi32we6HAAABi0CPAAA6Cmz2SwiGo1Gp9OdtWvLli3XX399RkZGREREREREdnb2smXL3nvvPY/H0+5TrVu37rLLLktMTDQajWlpabfffvvRo0fPbdbU1HTuhPPtbgQAYNDgFnoAANAjqqoeP35cREaOHKnX/+erhdPpvOmmm9544422jRVFURTlgw8+WLp06fvvv9828Le0tFx99dXr169v3VJcXPzCCy+89tprZz0JAABDEwEeAAD0yF//+tempiYRufnmm9tuf/LJJ73BOzMz87bbbsvIyFBV9ejRoy+//PLRo0c/+uij1atX33vvva3tb7rpJm96j4qKuvbaa2fMmFFSUvLhhx9u3779uuuuc7vd/fu2AADwOwR4AABwPhoaGk6dOvXGG2889dRTIjJnzpz777+/bYPnnntORMaOHfvll19GRES0bv/+978/YcKE4uLi3Nzc1gD/8ccfe2ewHzNmzAcffJCRkeHd/uCDD95zzz3PPvts/7wpAAD8GWPgAQBAF/7f//t/mnOYTKbx48c/8sgjdrv9hz/84b/+9S+j0dh6iN1u93g8w4cP/8EPftA2vYuIyWS6+OKLRaSoqKh145/+9Cfvg1dffbU1vYuIVqt95plnsrOz+/QNAgAQELgCDwAAeiQ4ODg+Pt5gMJy18dSpUx0dUlVVddaW3bt3i8jChQtnzJhx1i6NRnPvvffedtttvVQvAACBigAPAAC6sHLlysWLF5+10eFwFBUVrVu37vTp0z/72c8OHz7c+VRz5eXlhYWFu3bt2rhx48aNG9vuamhoqKioEJGZM2e2e+zcuXN79g4AABgMCPAAAKALM2fOvP3229vd9etf/3rhwoW7d+9+8803H3roofHjx7fde/jw4Zdffnnz5s1Hjx71TnTXrsLCQu+D9PT0dht415kHAGCII8ADAIDzFxER8fOf/3zZsmUisnnz5rYB/rHHHnvooYe8s8cbDIbJkydnZWVlZmZeeOGFa9asefnll1tbBgcHex9oNJp2X8VoNIaGhjY3N/fhOwEAwO8R4AEAQI9MmjTJ+8B7G7zXp59++uCDD4qId6K7Sy65pDWli8g777zT9hnS09M1Go2qqm2ntWurqqqK9A4AAAEeAAD0SGJiovdBbW1t68a//e1vIhISEvLpp5/Gx8efdYjL5Wr7V6PRmJSUVFpaumvXrnZfYv/+/b1YMAAAAYpl5AAAQI+oqup90HZu+ZKSEhFJT08/N72rqrpnz56zNnonn9+4caN3OvqzPPbYY71YMAAAAYoADwAAekfbW+i9a7kXFRVVVla2bdPS0vLDH/7Qe0XdOzze6/vf/773wY033njWjfSPPfbYpk2b+q5sAAACBQEeAAD0iF6vN5lMIlJWVta68bLLLhMRm822YMGCt95668CBA7m5uatXrx43btyf/vSnsLAwETly5MiGDRsaGhpEZPHixVdffbWIKIoyffr0e+6554033njmmWeWLFny4IMPBgcHZ2VlDczbAwDAbzAGHgAA9NTIkSMPHDhw/Pjx/fv3T5w4UUSWL19+yy23vPTSS/n5+ddee21rS61W+8ADD0ydOvVb3/qWx+O59NJLly9f7p3T7m9/+1tTU9MHH3xQU1PzzDPPtB5iNBpfe+21devWKYrS/28NAAD/wRV4AADQU4sXLxYRVVW9V9G9XnzxxXfeeWfRokUpKSnBwcEjRoy45ZZb9u/f//vf/37lypW333672WyOjo5uXfvdaDS+//77a9euXbp0aXx8fFBQ0LBhw2644YY9e/ZcddVVA/PGAADwJ5rWiWcAAAAAAIDf4go8AAAAAAABgAAPAAAAAEAAIMADAAAAABAACPAAAAAAAAQAAjwAAAAAAAGAAA8AAAAAQAAgwAMAAAAAEAAI8AAAAAAABAACPAAAAAAAAYAADwAAAABAACDAAwAAAAAQAAjwAPD/268DEgAAAABB/1+3I9AXAgDAgMADAADAgMADAADAQFxWEqejjWjgAAAAAElFTkSuQmCC) + + + + + +#### Figure XV, Scatterplot of Radii vs Range of Steps + +![img](data:image/png;base64,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) + + + + + +#### Figure XVI, Scatterplot with Quadratic Regression of Radii vs Range of Steps + +![img](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABUAAAAPACAIAAAB7BESOAAAACXBIWXMAAB2HAAAdhwGP5fFlAAAgAElEQVR4nOzdeXxTVf7/8ZMmbbrShUJLN0B2amWxCIgiIDtIgRFXZlBEFAdxA+SrjDOODMyIoMCAoIiggKMiS1laEAFFZBVQ2XfaQlsopXvTpEl+f9yZ+4u3aXOhTZO0r+cfPtJPzrn3NDfSvHPvPUdjtVoFAAAAAABwb16uHgAAAAAAAHCMAA8AAAAAgAcgwAMAAAAA4AEI8AAAAAAAeAACPAAAAAAAHoAADwAAAACAByDAAwAAAADgAQjwAAAAAAB4AAI8AAAAAAAegAAPAAAAAIAHIMADAAAAAOABCPAAAAAAAHgAAjwAAAAAAB6AAA8AAAAAgAcgwLu7fv36aRwJDg7u3Lnzww8//Pe//z09Pd0l43z77belwSxcuNC2PmLECKn+3Xffqal7EE85NPXNlStXxo4d27p1az8/v2bNmuXl5d3qFgwGw8qVK8eMGRMfHx8eHu7j4xMZGdmpU6ekpKRly5bdvHnTGcMGAAAAHCLA1wUFBQVHjhz55ptv/vrXv7Zo0eIf//iHq0eE/+LQ1LKsrKwOHTp8+umnZ8+eNRgMly9fNpvNt7SFZcuWxcTE/PGPf/zss89OnDhx48YNk8mUnZ199OjR5OTkZ555JjIycvr06eXl5Xa75+fn5+fnFxQU1MRvAwAAAPyOztUDgFqBgYEhISEV6yaTKScnR04pJpNp+vTpZWVlf//732t3gPUXh8Z9/PWvf71x44YQIjAwcOjQoSEhIXq9Xn33F1544cMPP5R/1Gq1MTExkZGR2dnZGRkZUmg3Go3/+Mc/duzYsXXr1qCgINvuZrNZeidERkZmZmbWzK8EAAAA/A8B3mM8//zzs2fPtvuU2WxOS0tbsGDBwoULjUajEGLmzJlPPvlkmzZtaneMdiQmJkqxJzw8XE3dE3nooamTDh48KD1ITU3t0aPHLfVdtGiRnN47deo0bdq0kSNH6nT//UfSbDbv27dv1qxZmzdvFkLs3bt34sSJK1asqLmxAwAAAA5wCX1doNVqmzdvPnfu3H/9619SxWw2f/rpp64dleTNN9/cuHHjxo0bO3TooKZex7jzoamT5PPe99xzzy11LCsrmz59uvS4T58++/bte+SRR+T0LoTQarU9evTYtGnT3Llzpcpnn32WkpJSE6MGAAAAVCHA1ykvvfRSq1atpMe7d+927WBgi0NTy7y8bu0ft23btkmz02k0mi+++MLHx6eylq+88sqwYcOkx4sXL67OIAEAAIBbQoCvUzQaTefOnaXHWVlZrh0MbNXmocnPzy8tLXXqLuqeEydOSA/atWvXuHHjqhsnJSVJD44ePercYVWutLS0uLjYarW6agAAAACofQT4uiYuLk564O3tbbfB8ePHp0yZ0rVr18jISL1e36RJky5duowaNSo5OdlisVS98V27do0dO7ZVq1b+/v7h4eGJiYkzZsy4du1aFV0ef/xxu8vFVVavzIwZM6T2nTp1qqLZihUrpGbR0dGKX6e0tPSDDz5ISkq68847AwICYmJievbs+fzzz585c0bNAKrPGYdmypQp0u97/PhxIcTKlSs7duwYEhLi7+/v7+/foUOHJ5544tChQ1UP7OzZs6+++mq7du0CAgIaN27cs2fPjz76yGQyCSG6d++u0WgaNWpUWV+LxfL1118/9thjLVq08Pf3j4yM7NGjx6uvvnrhwgU1r0kVcnJy3n333QceeCA6Olqv1zdu3DgxMfGNN96we7zk4y5/OaLT6aSKNKedQ8XFxdIDNZH4vvvu69WrV69eve68806p8pe//EWj0ciX3GdlZUl7Dw0Nrdj9Vl+0K1euSFt79tlnhRCHDx8eMGBASEhIYGCgt7d3TEzMgAEDPv74Y2mShcq4/P0PAACAGmCFe+vbt690pCZPnqym/aOPPiq1f/DBBxVPGQyGcePGaTSayt4MLVu2/OWXX+xutrCwcNSoUXZ7hYeHb968+W9/+5v047///W/bjo899phU3759u5p6ZWxjxvnz5ytrNmjQIKnN66+/bltfvnx5RESE3fFrtdoXXnihvLxczTBsucOhmTx5stTg2LFjr776qt2+Go1m0qRJlY1qwYIFvr6+FXt17tz5woUL3bp1kw6x3b7Hjx+XLytQ8PLyGjduXFlZmZpXpqJPP/3U7sT+QgidTjdlyhSz2Wzbfvny5ZW9dDk5OWr2KG/By8trz549tzpg+f55hZCQEEXL23jRMjIypAbjxo1bvXp1ZV8AtW3b9ujRo5X9djX+/gcAAEDtI8C7u1tKieXl5S1btpTa//3vf1c8K2dmIYSvr298fHyvXr06dOjQoEEDuR4T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zs7OVswep9Ppunfv/v7776ekpEiVH374Qf0Mc7ehxg9NdXTq1El68Ntvv1XW5tixY3brnTt3lh6cOnWqil0UFRWdP3/+/Pnz8glzh+QtHzp0qIpm8rNy+2pq2rSpNNVfcXGxyonx5N/ddma7KtTUiyZPhlfRyZMnpbeWRqORj6/7vP8BAABQfQT4uka+bzYnJ0cuyqdS77333squZK4sgcurec2dO7egoMBum08//VTlVF41YuTIkdKqdRs3bjSZTNL18zqd7oknnqjY+Omnn46MjIyMjFy6dKndrfXq1UuaK768vNypv0WNH5rqkFcyS05Otl1mXGY2mz/88EO7fbt37y69Yrt27frll18q28XEiRNbtmzZsmVLeSlyh3r16iU92L9/vzQrYUXXrl379NNPpce9e/dWueWq6fX6Hj16SI9ffPFFh3fsFxUVyWvIVbbcnUJNvWizZs2qrO/bb78tPejQoYO8kqL7vP8BAABQfQT4uka+F932s7g8nXhlVyb//PPPc+fOtfvUmDFjpLScm5v7xhtvVGxw+fJlOTnUjrCwsH79+gkh8vPzP/vss59++kkIMXDgQHmOLlt333239KCyRHTgwIHS0lIhhF6vr3qivmqq8UNTHZ06dbrvvvukUc2cObNig88++0y+Ul0hICDgj3/8o/T42WeflZcct7Vr166VK1cKIfR6/WOPPaZyVK1atZIz+f/93/+VlZUpGlgslqlTp0p7bNy48YgRI1Ru2aF33nlHerB3797nnntOmhPRrvLy8ocffjg7O1sIERAQMHr06IptKn4FUFMv2sGDB1etWlWxnpycLM8EYXuJvvu8/wEAAFB9BPi6JigoSHqQmZkpF+XLd1NTU5cvX27bvri4ePr06T169JAnnD937pxtg8jIyFdeeUV6vHDhwj/96U/yfbYmk2nz5s2JiYlXrlypOPe7U8lX0b/22mtSWKps+jr5zOrOnTsfeeSRS5cuyU9ZLJYtW7bIIXDkyJG3Opf7LanxQ1NN7733nnTUPvzww6lTp8rzlhsMhiVLlkyYMEGv10uVipcGvPnmm8HBwUKIgwcP3nvvvXv27JGfMplMS5cuHTp0qJSBn3nmGflssBozZ86Udrd3796BAwfaXuGflpY2aNAgeen1GTNmyCOsvgceeEC+guPjjz9OSEj4+OOPbb9VKS8vz8jIWLRo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4YZE/2VJdAAAAADJiYBX0uLFi1999dXt27f7/f6uo9Aul6uiokKn011wwQVDO7yB2LFjx9ixY0+cOPHWW2/p9frRo0fn5+cXFha2tLR0XdN49dVX//3vf49EIh988MEHH3wQvaKj67j6lClTbrvttkceeaSuri4YDFZUVFRUVHStX61W33zzzXPmzFm2bNmaNWvWr1/vdDqjr9VoNEVFRStWrOg6WX3gqHQAAAAAKYeAV1J+fn5paenevXufeuqpO++8U61W+/3+Rx55JBAILF68OKUvjJEk6fjx49ddd92qVasikcjx48ePHz/edaLB2LFj7777bo1Gc8455zz55JM1NTWyLHelu8ViufHGG2fMmCGE+NnPfnbo0KE33nijtrY2GAyqVCqLxXLuuecuW7as66j+kiVLlixZIoTw+/0ajaYfc7nR5wAAAACGHwJeYbfddts999yzadOmnTt3FhUVHTt2LBAIFBQUfOc73xnqoSngpZdeWrly5a9+9as333yztbW1oKBgwoQJV111VdfvJqxW63/913/JstzQ0NDY2JiRkZGXl9ftkvhJkybde++98Wwu1iT89DkAAACAEYiAV1h+fv6TTz750ksv7dix48iRI3a7ff78+d/85jeHzYzier3+gQceiM6cv3///h6XkSQpPz8/Pz+/f5ugzwEAAADgdAS88ux2+7//+78P9SiSEWUOAAAAAP1GwGOgyHIAAAAAGAQEPPqPdAcAAACAQaMa6gEAAAAAAIAzI+ABAAAAAEgBBDwAAAAAACmAgAcAAAAAIAUQ8AAAAAAApAACHgAAAACAFEDAAwAAAACQAgh4AAAAAABSAAEPAAAAAEAKIOABAAAAAEgBBDwAAAAAACmAgAcAAAAAIAUQ8AAAAAAApAACHgAAAACAFEDAAwAAAACQAgh4AAAAAABSAAEPAAAAAEAKIOABAAAAAEgBBDwAAAAAACmAgAcAAAAAIAUQ8AAAAAAApAACHgAAAACAFEDAAwAAAACQAgh4AAAAAABSAAEPAAAAAEAKIOABAAAAAEgBBDwAAAAAACmAgAcAAAAAIAUQ8AAAAAAApAACHgAAAACAFEDAAwAAAACQAgh4AAAAAABSAAEPAAAAAEAKIOABAAAAAEgBmqEeAGI6duzYt7/97USsORQKRf+g0fAPIBmFQiGVSqVS8fu1pCPLcjgc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) + + + + + +#### Figure XVII, Scatterplot of Radii vs Variance of Steps + +![img](data:image/png;base64,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) + + + + + +#### Figure XVIII, Scatterplot with Cubic Regression of Radii vs Variance of Steps + +![img](data:image/png;base64,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ZXnggQeku9atXr3aZDJJ58/r9Xr5jm5Kjz32WGRkZGRk5Ny5c+3urVevXtI0/mazudzPIiwsbPDgwdLy4sWLV6xYIX2nMHjw4KCgIFXnihyOinDV48o/QnPnzi3uIu0lS5YkJiYmJia2bNlSaunatat0XLZv315C8p80aVJ0dHR0dHTp7wPfq1cvaWHv3r3S3IdF3bp1a968edJy7969S7nnkvn4+HTv3l1afu655257xX5OTo58D7nibnenUlkvmnIuRpX33ntPWmjbtq18bYhz3mUAAADVHAG+CpKvRVf+lRwVFSUtFHfO8IEDB2bNmmV31bhx46S0nJaW9sYbbxTtcPnyZflveueoUaOGdLOxzMzMBQsW/PHHH0KIgQMH2r1VW8eOHaWF4rLKvn378vPzhRA+Pj6lmei7OGPGjJEfSL4m3+788xU5HBXhqscdMmSIdD52VlbWm2++WbTD8ePHf/jhB2lZPsc+ICDgkUcekZafeOIJ+ZbjStu3b1+4cKEQwsfHp4Sp/lWaNm0qZ/LXX3+9oKBA1cFqtb7yyivSI9aqVcvuHITl8/7770sLu3fvfvLJJ6WZF+0ym80PPvhgUlKSECIgIEC+4YJS0a8AKutF279//48//li0fdWqVfLPtvIUfae9ywAAAKozAnwVJNd75Xt3CcWJtRs2bPj++++V/XNzc998883u3bvLE86fP39e2SEyMnLKlCnS8uzZsx999FH5CliTybR27drY2Nhr164VnfvdoeSz6F988UUpxhQ3fZ1c89y2bdtDDz106dIleZXVal23bp0czx544IGyzq+udO+990pz/iUnJ2/dulUIERAQcM899xTtWZHDURGuelwvL68PPvhAWp49e/aIESOUZ25v27ZtyJAhBoNBCNG5c2f5rGwhxL///e+QkBAhxP79+7t167Zr1y55lclkmjt37r333itl4Mcff7zoTIEl+OCDD6RzEHbv3j1w4MBjx47Jq65cuTJo0CD51uvTpk3z8fEp+5O2r2fPnvJ5It98801MTMw333yj/D7FbDYnJiZ+9dVX7du3l2cTnDZtmt3Qm5mZKb1uSpX1oo0fP/6TTz6Rr8RJS0ubNm3asGHDpLdbixYtlFesOO1dBgAAUK3Z4Pb69u0rHayXXnqpNP3lP5QHDRqkbH/ooYfk4966deuxY8f+85//7Ny5szwj9+jRo6UFjUYzYsSIOXPmyNvm5+d37dpV+ZMTERERGxvr6+sr/dfb21u+7fx///tf5ePKJb4tW7aUpr2UMjMzlbEqLCzMYDAU11l5+rF0y72ePXt26dKlZs2acnvt2rUTExPLMRIl1UX4o0ePLq5nRQ7HpEmTpFXff/99cfsv7uWtyOO+9NJL0iplo0qXLl2kPufPn1etGj9+vPLFadSoUa9evZR3hg8JCTl27JhqqxUrVkgngEgaNGjQu3fvLl26hIWFyY19+/Y1Go3FDak4M2fOVI4nLCzsrrvukk9SkIwdO9butnKcNpvNZX1ck8lUdFoEqS4dERFRdO73yZMnF92JFNGFEF26dHnmmWekOwvIyveiJSYmSqvq1q0rX8gg3cu9efPmyoEFBwcnJCSohuS0dxkAAEC1RYD3AGUN8PIpyjqdbs+ePXJ7RkaGXCVTiYyMjI+Pt9lsjRs3lhvvvPNO5W6zsrIeeOABu5uHhYWtWrVKvs2VcwK8zWYbOnSoPIann366hJ4ZGRnSKffF6d+//7lz58o3DKXNmzcrd7ty5coShlTuw1GRAF+Rx61ggLdarW+88YYyWCo1btx4//79dve5adMmVa6W6XS68ePHZ2ZmFjeeks2dO1e+UaKKl5fXa6+9ZrFY7G5YkQBvs9ksFsv//vc/ZbK1q169ej/++KPdPcjnyUtCQ0NVHcrxoskBvkWLFjdu3FB9ZyeLjo4umt5tTnyXAQAAVFvcRq4KGjx48LRp04QQFotl9OjR8q2wQkJCdu7c+fPPP//4449nz569dOlScHBwq1athg4dOmHCBKkAu2TJkkmTJh05ciQsLEyefF4SFBS0dOnSrVu3/vDDDzt37rx+/bper69fv/6QIUOefvrpqKioEmbMcpBRo0atWLFCWi7u/HlJSEjIpk2b1q9f/8svv1y4cOHy5cs3b96MjIxs3Lhx06ZNJ06cqHqy5danT586depIFy+EhIQMGDCghCFV5HCUm6seVwih0WimT58+bty4b7/9dsOGDVevXs3JyQkPD2/fvv2wYcMeffTR4s5U79ev39mzZ+fPn79q1apjx44lJydHREQ0a9asVatWzz33XPPmzcs9pMcff3zIkCFz585dt27duXPnUlNTg4ODGzZsOGDAgPHjx0dHR5d7zyXTarUTJ058+OGHN23atG7dugMHDiQnJ6ekpGi12pCQkMaNG3fo0GHw4MH9+/cv7sqU2bNnR0RELFu27MaNG2FhYc2aNVN1qOCLFhkZuXPnzoULF/74449Hjx5NS0sLDw9v3br18OHDH3vsMbtHymnvMgAAgGpLY7vdNMgAgOrg2rVrUtG+RYsWp06dcvVwAAAAoMYkdgAAAAAAeAACPAAAAAAAHoAADwAAAACAByDAAwAAAADgAQjwAAAAAAB4AG4jBwAQQgidTteoUSMhRL169Vw9FgAAANjBbeQAAAAAAPAAnEIPAAAAAIAHIMADAAAAAOABCPAAAAAAAHgAAjwAAAAAAB6AAA8AAAAAgAcgwAMAAAAA4AEI8AAAAAAAeAACPAAAAAAAHoAADwAAAACAByDAAwAAAADgAQjwAAAAAAB4AAI8AAAAAAAegAAPAAAAAIAHIMADAAAAAOABCPAAAAAAAHgAAjwAAAAAAB5A7+oBoFhffPHFr7/+6qCdW61WaUGr5Uscd2S1WjUajUajcfVAoGaz2Ww2mxCCA+SepAPEJ5t74lePm+NXj9uSf/Xw3nFP0ocbR8cNedCfbZMmTerXr19pehLg3Vd6errBYLj33nsdsfP8/HwhhEaj8fX1dcT+UUH5+fne3t46nc7VA4GayWQym81CCA6QezIajTabzcfHx9UDgZrNZjMYDEIIrVbLAXJD0gHy8fEhhLgho9FosViEEBwg91RQUCCE4JPNDVmtVuno6HQ6b29vVw/HDovFsnDhQiFEbm5uKTchwLu12rVrP/fcc47Yc0pKihBCp9OFhYU5Yv+oCJvNlpqaGhQUxG8CN5Sbmyt9/xUcHOyevwmquZycHLPZHBoa6uqBQM1qtaalpQkhvLy8QkJCXD0cqFkslvT09JCQEC8vL1ePBWrZ2dlSCAkNDdXr+evd7WRmZmo0muDgYFcPBGpmszkjI0MI4ePjExQU5Orh2GE0GqUAX3p8hwcAAAAAgAcgwAMAAAAA4AEI8AAAAAAAeAACPAAAAAAAHoAADwAAAACAByDAAwAAAADgAQjwAAAAAAB4AAI8AAAAAAAegAAPAAAAAIAHIMADAAAAAOABCPAAAAAAAHgAAjwAAAAAAB6AAA8AAAAAgAcgwAMAAAAA4AEI8AAAAAAAeAACPAAAAAAAHoAADwAAAACAByDAAwAAAADgAQjwAAAAAAB4AAI8AAAAAAAegAAPAAAAAIAHIMADAAAAAOABCPAAAAAAAHgAAjwAAAAAAB6AAA8AAAAAgAcgwAMAAAAA4AH0rh4AAAAAAACVyWKx7Nix49ixY7m5ufXr1x84cGBERISrB1UJCPAAAAAAgCrCaDR+8cUXH3/8cXJystyo0+mGDRs2Y8aM6OhoF46t4gjwAAAAAICqIC0tbejQoTt27NDr9QMGDGjTpo23t1dRh1MAACAASURBVHdiYuKGDRuWLFmyadOmxYsXDxo0yNXDLD8CPAAAAADA45lMpuHDh+/YsSM2NvaHH36Ijo7OyMgQQvj4+Oj1+mnTps2YMWP48OG//fZbXFycqwdbTgR4AAAAAIDH+/rrr7dv396hQ4dt27bt3r37888/P3PmTG5ubr169fr37//CCy9ERES88MILTzzxxMGDB7Vaj5zQnQAPAAAAAPBsNptt5syZWq32jTfe6NOnz/79+5Vrly9f/tprr73//vvdunX7448/NmzYMHjwYFcNtSI88lsHAAAAAABkx44du3z5cqtWrR577LH9+/d37Njx22+/3bVr18GDB1euXPnEE0/k5eVNnjzZ19dXCLF27VpXj7ecqMADAAAAADzbn3/+KYQ4f/68wWB499133377bYvFIl0DHx0dff/99z/55JP33Xff1q1bhRAXLlxw8XDLiwo8AAAAAMCzGY1GIYTBYHj66affeecdjUaj6tCxY8fVq1frdDohRG5urguGWBkI8AAAAAAAz1azZk0hhF6vnz59enF9Onbs2Lt3byGExWJx3sgqFQEeAAAAAODZbDab9K/BYCihm1So91wEeAAAAACAZ0tOThZCWCyW559/XgrzRW3ZsmXHjh1CCOlEek9EgAcAAAAAeDY/Pz8hRFBQUHx8/FNPPVVQUKDqsH79+gcffFDK9kFBQS4YYmVgFnoAAAAAgGdr1qyZECIqKio9Pf3rr7/euHHjhAkTWrdu7evre+3atRUrVqxdu1aj0dx3332rV69u3ry5q8dbTgR4AAAAAIBna9GiRYsWLU6dOrV06dIFCxasXLnyrbfeUnZo0KDBJ598MnXqVCHEkCFDXDTMiiLAAwAAAAA83htvvPHoo4+++uqru3fvnjZt2vLly0+cOGEwGOrVqzdgwIABAwa88847x44d6969e69evVw92HIiwAMAAAAAPN7YsWNXrFixbNmyrl27fvvtt6+/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) + + + + + +#### Figure XIX, Scatterplot of Radii vs Skewness + +![img](data:image/png;base64,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) + + + + + +### R Code + +```R +rm(list=ls()) +library(moments) +library(ggplot2) + +simulateRoom = function(r) { + n = 1000 + results = numeric(n) + x = 0 + y = 0 + dist = 0 + num = 0 + for (i in 1:n) { + while(dist < r) { + deg = runif(1, min=0, max=360) + newx = cos(deg) + newy = sin(deg) + x = x + newx + y = y + newy + num = num+ 1 + dist=(x^2 + y^2)^0.5 + } + results[i] = num + x= 0 + y = 0 + dist = 0 + num = 0 + i = i + 1 + } + return(results) +} + +repetitions = 3 +radii = c(2, 3, 4, 5, 10, 25, 50, 100) + +median_stepcount = c() +mean_stepcount = c() +variance_stepcount = c() +range_stepcount = c() +skewness_stepcount = c() +for (r in radii) { + room_data = data.frame() + print(paste("Currently simulating r =", r)) + for (i in 1:repetitions) { + simulation = simulateRoom(r) + + ## Summary Statistics + variance = var(simulation) + skewness_ = skewness(simulation) + range_data = range(simulation) + + room_data_temp = data.frame(i, mean(simulation), median(simulation), variance, range_data[2] - range_data[1], skewness_) + names(room_data_temp) = c("Trial", "Mean", "Median", "Variance", "Range", "Skewness") + room_data = rbind(room_data, room_data_temp) + + median_stepcount = c(median_stepcount, median(simulation)) + mean_stepcount = c(mean_stepcount, mean(simulation)) + variance_stepcount = c(variance_stepcount, variance) + range_stepcount = c(range_stepcount, range_data[2] - range_data[1]) + skewness_stepcount = c(skewness_stepcount, skewness_) + + simulation = data.frame(simulation) + print(ggplot(simulation, aes(x = simulation)) + + geom_histogram(color = 'black', fill = 'white') + + xlab("Steps") + + ylab("Count") + + ggtitle(paste("Distribution of r =", r)) + + theme_bw()) + } + print(room_data) +} + +## Show the probability distribution +library(MASS) +distribution = fitdistr(simulation$simulation, "geometric") +probability_simulation = data.frame(simulation, + rgeom(1:1000, distribution$estimate['prob'])) +names(probability_simulation) = c("simulation", "geometric") +ggplot(data = probability_simulation, aes(x = simulation)) + + geom_histogram(aes(y = ..density..), color = 'black', fill = 'white') + + geom_density(aes(x = geometric), fill = '#0000AA', alpha = .5) + + xlab("Steps") + + ylab("Probability Density") + + ggtitle("Probability Density Histogram with Geometric Overlay") + + theme_bw() + +## Calculate QQ Plot of Geometric Distribution and Sample +yquantiles = quantile(simulation$simulation, c(0.25, 0.75)) +xquantiles = qgeom(prob = distribution$estimate['prob'], c(0.25, 0.75)) +slope = diff(yquantiles) / diff(xquantiles) +intercept = yquantiles[1] - slope * xquantiles[1] +ggplot() + aes(sample=simulation$simulation) + + stat_qq(distribution=qgeom, dparams = distribution$estimate['prob']) + + geom_abline(intercept=intercept, slope=slope) + + ggtitle("QQ Plot of Geometric Distribution") + + xlab("Theoretical Quantiles") + + ylab("Sample Quantiles") + + theme_bw() + + +## Create a dataframe +room_simulation_data = data.frame(as.vector(sapply(radii, function(x) { rep(x, repetitions)})), mean_stepcount, median_stepcount, range_stepcount, skewness_stepcount, variance_stepcount) +names(room_simulation_data) = c("radii", "mean_stepcount", "median_stepcount", "range_stepcount", "skewness_stepcount", "variance_stepcount") +######### ANALYSIS OF MEANS +ggplot(room_simulation_data, aes(x = radii, y = mean_stepcount)) + + geom_point(shape = 21, size = 2) + + xlab("Radii") + + ylab("Mean Steps") + + ggtitle("Radii vs Mean Steps") + + theme_bw() + +## Quadratic Regression of Means +quadratic_mean_model = lm(mean_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data) +quadratic_mean_model_summary = summary(quadratic_mean_model) +ggplot(room_simulation_data, aes(x = radii, y = mean_stepcount)) + + geom_point(shape = 21, size = 2) + + geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) + + xlab("Radii") + + ylab("Mean Steps") + + ggtitle("Radii vs Mean Steps") + + theme_bw() + +## Analysis of Quadratic Regression of Means +quadratic_mean_coefficients = as.vector(quadratic_mean_model$coefficients) +print(paste("The quadratic regression equation is: Mean Steps =", quadratic_mean_coefficients[1], "+", quadratic_mean_coefficients[2], "radii", quadratic_mean_coefficients[3], "radii^2")) +print(paste(quadratic_mean_model_summary$adj.r.squared * 100, "% of the variation of the means is accounted for by the Quadratic Model", sep = "")) + + +######### ANALYSIS OF MEDIANS +ggplot(room_simulation_data, aes(x = radii, y = median_stepcount)) + + geom_point(shape = 21, size = 2) + + xlab("Radii") + + ylab("Median Steps") + + ggtitle("Radii vs Median Steps") + + theme_bw() + +## Quadratic Regression of Medians +quadratic_median_model = lm(median_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data) +quadratic_median_model_summary = summary(quadratic_median_model) +ggplot(room_simulation_data, aes(x = radii, y = median_stepcount)) + + geom_point(shape = 21, size = 2) + + geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) + + xlab("Radii") + + ylab("Median Steps") + + ggtitle("Radii vs Median Steps") + + theme_bw() + +## Analysis of Quadratic Regression of Medians +quadratic_median_coefficients = as.vector(quadratic_median_model$coefficients) +print(paste("The Quadratic Regression Equation is: Median Steps =", quadratic_median_coefficients[1], "+", quadratic_median_coefficients[2], "radii", quadratic_median_coefficients[3], "radii^2")) +print(paste(quadratic_median_model_summary$adj.r.squared * 100, "% of the variation of the medians is accounted for by the Quadratic Model", sep = "")) + + +######### ANALYSIS OF RANGES +ggplot(room_simulation_data, aes(x = radii, y = range_stepcount)) + + geom_point(shape = 21, size = 2) + + xlab("Radii") + + ylab("Range of Steps") + + ggtitle("Radii vs Range Steps") + + theme_bw() + +## Quadratic Regression of Ranges +quadratic_range_model = lm(range_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data) +quadratic_range_model_summary = summary(quadratic_range_model) +ggplot(room_simulation_data, aes(x = radii, y = range_stepcount)) + + geom_point(shape = 21, size = 2) + + geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) + + xlab("Radii") + + ylab("Range of Steps") + + ggtitle("Radii vs Range of Steps") + + theme_bw() + +## Analysis of Quadratic Regression of Ranges +quadratic_range_coefficients = as.vector(quadratic_range_model$coefficients) +print(paste("The Quadratic Regression Equation is: Range of Steps =", quadratic_range_coefficients[1], "+", quadratic_range_coefficients[2], "radii", quadratic_range_coefficients[3], "radii^2")) +print(paste(quadratic_range_model_summary$adj.r.squared * 100, "% of the variation of the ranges is accounted for by the Quadratic Model", sep = "")) + + + +######### ANALYSIS OF SKEWNESS +ggplot(room_simulation_data, aes(x = radii, y = skewness_stepcount)) + + geom_point(shape = 21, size = 2) + + xlab("Radii") + + ylab("Skewness") + + ggtitle("Radii vs Skewness Steps") + + theme_bw() + + +######### ANALYSIS OF VARIANCES +ggplot(room_simulation_data, aes(x = radii, y = variance_stepcount)) + + geom_point(shape = 21, size = 2) + + xlab("Radii") + + ylab("Variance of Steps") + + ggtitle("Radii vs Variance Steps") + + theme_bw() + +## Cubic Regression of Variance +cubic_variance_model = lm(variance_stepcount ~ poly(radii, 3, raw = T), data = room_simulation_data) +cubic_variance_model_summary = summary(cubic_variance_model) +ggplot(room_simulation_data, aes(x = radii, y = variance_stepcount)) + + geom_point(shape = 21, size = 2) + + geom_smooth(method = "lm", formula = y ~ poly(x, 3, raw = T), se = T) + + xlab("Radii") + + ylab("Variance of Steps") + + ggtitle("Radii vs Variance of Steps") + + theme_bw() + +## Analysis of Cubic Regression +cubic_variance_coefficients = as.vector(cubic_variance_model$coefficients) +print(paste("The Cubic Regression Equation is: Variance of Steps =", cubic_variance_coefficients[1], "+", cubic_variance_coefficients[2], "radii", cubic_variance_coefficients[3], "radii^2", cubic_variance_coefficients[4], "radii^3")) +print(paste(cubic_variance_model_summary$adj.r.squared * 100, "% of the variation of the variations is accounted for by the Cubic Model", sep = "")) +``` + diff --git a/content/presentations.md b/content/presentations.md new file mode 100644 index 0000000..4d61e2c --- /dev/null +++ b/content/presentations.md @@ -0,0 +1,29 @@ +--- +title: Presentations +description: This is a page of presentations I was a part of. +--- + +## Expedited Learning via Interactive Demonstrations + +On December 4, 2019, I gave a defense on my honors research in the incorporation of demonstration data throughout a reinforcement learning algorithm. I have shown that this technique expedites the learning process. + +[Slides PPTX](/files/research/ExpeditedLearningInteractiveDemo.pptx) + +## Building a Linux Cluster + +In June 2019, Stefano Coronado and I were volunteered to give a talk at the Fredericksburg Linux Users group on our experiences building a Beowulf cluster for our University. + +[Slides PDF](/files/slides/buildinglinuxcluster.pdf) + +## Embezzlement of Parking Meter Funds: A Computational Approach to Hypothesis Testing + +I was invited to give a talk to the Data Science Group at the University of Mary Washington called the Data Mavens. It was a 25 minute presentation on the bootstrap resampling technique with code on how to get started. + +[Slides PDF](/files/slides/embezzlement.pdf) + +## Similyrics: A Music Recommendation Engine Based on Lyrics +At the VCU RamHacks hackathon, Clare Arrington, Harrison Crosse, and I demoed our product Similyrics. It's a web application that takes your favorite song, grabs the lyrics, and finds a song from a database that closely matches to the song you have chosen lyric wise. + +[Slides PDF](/files/slides/similyrics.pdf) + + diff --git a/content/projects/mathio.md b/content/projects/mathio.md new file mode 100644 index 0000000..99aa6eb --- /dev/null +++ b/content/projects/mathio.md @@ -0,0 +1,22 @@ +--- +id: 1609 +title: Math I/O +date: 2016-10-23T23:33:41+00:00 +author: rozek_admin +layout: revision +guid: http://brandonrozek.com/2016/10/362-revision-v1/ +permalink: /2016/10/362-revision-v1/ +--- +Screenshot of the Math I/O Website + +### [Math I/O](http://math-io.com) {.project-title} + +Math I/O is a website I founded with [David Thames](http://davidcthames.com) and Stephen Shamaiengar. The goal of this website is to help reinforce high school level math concepts in the form of enjoyable games. Most of the games are made using HTML5 Canvas and Javascript. You can check them out [here](http://math-io.com/). + + + +I ran Math I/O for a year until I moved away from the area. During that year, I worked on the Darts game, Speed Transformations, and Theta. I then took about a year off to get adjusted to my new place when I moved. + +While I was away, Math I/O gained many new people, making it hard for them to work as one large group. David then decided to split the group up into smaller teams, inviting me to come back and lead one. I never ran a team remotely before, so I was excited to see how it would be like. + +The team I lead are mostly full of people starting out in programming. To help them out, I started giving lectures once a week to introduce concepts, and posted them here on my writings page. We would then practice these concepts while making a new game during the meetings. I couldn’t ask for a better team, their enthusiasm drives me to keep working at Math I/O. \ No newline at end of file diff --git a/content/projects/sentenceworthy.md b/content/projects/sentenceworthy.md new file mode 100644 index 0000000..8fd70a4 --- /dev/null +++ b/content/projects/sentenceworthy.md @@ -0,0 +1,20 @@ +--- +id: 1608 +title: Sentence Worthy +date: 2016-10-23T23:33:11+00:00 +author: rozek_admin +layout: revision +guid: http://brandonrozek.com/2016/10/360-revision-v1/ +permalink: /2016/10/360-revision-v1/ +--- +SentenceWorthy + +### [Sentence Worthy](http://sentenceworthy.com) {.project-title} + +Sentence Worthy is a side project created by [Tori Dayton](http://toridayton.com) and I. We combine both of our passions, writing and photography, and make something for others to enjoy. Have a look at our [creation](http://sentenceworthy.com). + + + +I am the main developer and photographer of this site. I head out every so often and take pictures of whatever interests me. Then, I email Tori my choice picks and she tells me what she wants to do with the pictures and what ideas she has for them. I then edit the picture with her ideas in mind. After we go back and forth on the picture edits, Tori sends me a one sentence story she made that goes along with the picture. The picture and story then get published together onto the website. Hence the tagline, every picture is worth a sentence. + + \ No newline at end of file diff --git a/content/projects/toridayton.md b/content/projects/toridayton.md new file mode 100644 index 0000000..eaa2d11 --- /dev/null +++ b/content/projects/toridayton.md @@ -0,0 +1,18 @@ +--- +id: 1607 +title: ToriDayton.com +date: 2016-10-23T23:32:34+00:00 +author: rozek_admin +layout: revision +guid: http://brandonrozek.com/2016/10/364-revision-v1/ +permalink: /2016/10/364-revision-v1/ +--- +Screenshot of Tori Dayton's website + +### [Tori Dayton](http://toridayton.com) {.project-title} + +Tori Dayton is a great friend and poet, this is the site I made for her to showcase her writings. It’s the first WordPress project I worked on and it set the tone for all the future ones I did. Check out her [writings!](http://toridayton.com/work) I’m a fan of her work. (Not biased at all) + + + +Fun Fact: I also worked on the [Tori Bot](http://toridayton.com/category/tori-bot/) on the site. Tori Bot takes existing poems and tries to generate a new one using the [Natural Language Toolkit](http://www.nltk.org/) library made for Python. \ No newline at end of file diff --git a/content/research.md b/content/research.md new file mode 100644 index 0000000..7d0e3f7 --- /dev/null +++ b/content/research.md @@ -0,0 +1,77 @@ +--- +Title: Research +Description: A list of my research Projects +--- + +[Quick List of Publications](publications) + +## Computer Science / Data Science Research + +### Reinforcement Learning + +**Deep Reinforcement Learning:** With Dr. Ron Zacharski I focused more on a particular instance of Reinforcement Learning where deep neural networks are used. During this time, I built out a Reinforcement Learning library written in PyTorch. This library helps me have a test bed for trying out different algorithms and attempts to create my own. + +One particular problem I'm fascinated by is how to make Reinforcement Learning algoirthms more sample efficient. This means, how can we make it so that it learns more from every observation or make it so that we can achieve our goal quicker? + +[RL Library on Github](https://github.com/brandon-rozek/rltorch) + +[Interactive Demonstrations Library](https://github.com/brandon-rozek/gyminteract) + +[Honors Thesis](/files/research/honorsthesis.pdf) + +[Honors Defense](/files/research/ExpeditedLearningInteractiveDemo.pptx) + +[QEP Algorithm Slides](/files/research/QEP.pptx) + +[More...](deepreinforcementlearning) + +**Reinforcement Learning:** Studied the fundamentals of reinforcement learning with Dr. Stephen Davies. We went over the fundamentals such as value functions, policy functions, how we can describe our environment as a markov decision processes, etc. + +[Notes and Other Goodies](reinforcementlearning) + +[Github Code](https://github.com/brandon-rozek/ReinforcementLearning) + + +### Symbolic Methods +Worked with Dr. Andrew Marshall under an ONR grant in collaboration with University at Albany, Clarkson University, and the Naval Research lab in order to automatically generated and verify cryptographic algorithms. + +During that time period I built a free algebra library, rewrite library, parts of the crypto tool, and dabbled in Unification algorithms. We're hoping to open source the code base by 2021. (Ping me if its past due) + +Currently I'm an external collaborator focused on strengthing the rewrite library. My dream is to slowly work towards building an easy to use theorem prover. + +### Programming Languages + +Studying the design of programming languages. So far I made an implementation of the SLOTH programming language, experimenting with what I want my own programming language to be syntatically and paradigm wise. + +[SLOTH Code](https://github.com/brandon-rozek/SLOTH) + +Before this study, I worked though a book called "Build your own Lisp" and my implementation of a lisp like language is below. + +[Lispy Code](https://github.com/brandon-rozek/lispy) + +### Other + +**Competitive Programming:** Studying algorithms and data structures necessary for competitive programming. Attended ACM ICPC in November 2018/2019 with a team of two other students. + +## Math/Statistics Research + +Worked on an independent study on the topic of **Cluster Analysis**. This is where you try to group similar observations without knowing what the labels are. +I studied under the guidance of Dr. Melody Denhere, the link below gives you more of a description of the project along with my course notes. + +[Cluster Analysis Spring 2018](clusteranalysis) + +## Physics Research + +For the two projects below, I worked on Quantum Research in a physics lab with a fellow student Hannah Killian and an advisor Dr. Hai Nguyen. I mostly assisted with the software support for the project and assisted in the mathematics in whatever way I can. + +[Modeling Population Dynamics of Incoherent and Coherent Excitation](/files/research/modellingpopulationdynamics.pdf) + +[Coherent Control of Atomic Population Using the Genetic Algorithm](/files/research/coherentcontrolofatomicpopulation.pdf) + + +In order to circumvent the frustrations I had with simulation code taking a while, I applied and received funding to build out a Beowulf cluster for the Physics department. Dr. Maia Magrakvilidze was the advisor for this project. + +[High Performance Cluster for Research and Education Report (nicknamed LUNA-C)](/files/research/LUNAC.pdf) + +[LUNA-C Poster](/files/research/LUNACposter.pdf) + diff --git a/content/research/_index.md b/content/research/_index.md new file mode 100644 index 0000000..e69de29 diff --git a/content/research/clusteranalysis.md b/content/research/clusteranalysis.md new file mode 100644 index 0000000..9eebd18 --- /dev/null +++ b/content/research/clusteranalysis.md @@ -0,0 +1,22 @@ +--- +Title: Cluster Analysis +Description: A study of grouping observations +--- + +# Cluster Analysis +Cluster Analysis is the art of finding inherent structures in data to form groups of similar observations. This has a myriad of applications from recommendation engines to social network analysis. + +This is an independent study, meaning that I will be studying this topic under the direction of a professor, in this case being Dr. Denhere. + +I have provided a list of topics that I wish to explore in a [syllabus](syllabus) + +Dr. Denhere likes to approach independent studies from a theoretical and applied sense. Meaning, I will learn the theory of the different algorithms, and then figure out a way to apply them onto a dataset. + +## Readings +There is no definitive textbook for this course. Instead I and Dr. Denhere search for materials that we think best demonstrates the topic at hand. + +I have created a [Reading Page](readings) to keep track of the different reading materials. + + +## Learning Notes +I like to type of the content I learn from different sources. A [notes page](notes) is created to keep track of the content discussed each meeting. diff --git a/content/research/clusteranalysis/notes.md b/content/research/clusteranalysis/notes.md new file mode 100644 index 0000000..5102309 --- /dev/null +++ b/content/research/clusteranalysis/notes.md @@ -0,0 +1,43 @@ +# Lecture Notes for Cluster Analysis + +[Lecture 1: Measures of Similarity](lec1) + +[Lecture 2.1: Distance Measures Reasoning](lec2-1) + +[Lecture 2.2: Principle Component Analysis Pt. 1](lec2-2) + +Lecture 3: Discussion of Dataset + +[Lecture 4: Principal Component Analysis Pt. 2](lec4) + +[Lecture 4.2: Revisiting Measures](lec4-2) + +[Lecture 4.3: Cluster Tendency](lec4-3) + +[Lecture 5: Introduction to Connectivity Based Models](lec5) + +[Lecture 6: Agglomerative Methods](lec6) + +[Lecture 7: Divisive Methods Part 1: Monothetic](lec7) + +[Lecture 8: Divisive Methods Part 2: Polythetic](lec8) + +[Lecture 9.1: CURE and TSNE](lec9-1) + +[Lecture 9.2: Cluster Validation Part I](lec9-2) + +[Lecture 10.1: Silhouette Coefficient](lec10-1) + +[Lecture 10.2: Centroid-Based Clustering](lec10-2) + +[Lecture 10.3: Voronoi Diagrams](lec10-3) + +[Lecture 11.1: K-means++](lec11-1) + +[Lecture 11.2: K-medoids](lec11-2) + +[Lecture 11.3: K-medians](lec11-3) + +[Lecture 12: Introduction to Density Based Clustering](lec12) + + diff --git a/content/research/clusteranalysis/notes/lec1.md b/content/research/clusteranalysis/notes/lec1.md new file mode 100644 index 0000000..5b61503 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec1.md @@ -0,0 +1,331 @@ +# Measures of similarity + +To identify clusters of observations we need to know how **close individuals are to each other** or **how far apart they are**. + +Two individuals are 'close' when their dissimilarity of distance is small and their similarity large. + +Special attention will be paid to proximity measures suitable for data consisting of repeated measures of the same variable, for example taken at different time points. + +## Similarity Measures for Categorical Data + +Measures are generally scaled to be in the interval $[0, 1]$, although occasionally they are expressed as percentages in the range $0-100\%$ + +Similarity value of unity indicates that both observations have identical values for all variables + +Similarity value of zero indicates that the two individuals differ maximally for all variables. + +### Similarity Measures for Binary Data + +An extensive list of similarity measures for binary data exist, the reason for such is that a large number of possible measures has to do with the apparent uncertainty as to how to **deal with the count of zero-zero matches** + +In some cases, zero-zero matches are equivalent to one-one matches and therefore should be included in the calculated similarity measure + +Example: Gender, where there is no preference as to which of the two categories should be coded as zero or one + +In other cases the inclusion or otherwise of the matches is more problematic + +Example: When the zero category corresponds to the genuine absence of some property, such as wings in a study of insects + +The question that then needs to be asked is do the co-absences contain useful information about the similarity of the two objects? + +Attributing a high degree of similarity to a pair of individuals simply because they both lack a large number of attributes may not be sensible in many situations + +The following table below will help when it comes to interpreting the measures + +![img](file:///home/rozek/Documents/Spring2018/Cluster%20Analysis/BinaryOutcomeTable.png?lastModify=1516246712) + +Measure that ignore the co-absence (lack of both objects having a zero) are Jaccard's Coefficient (S2), Sneath and Sokal (S4) + +When co-absences are considered informative, the simple matching coefficient (S1) is usually employed. + +Measures S3 and S5 are further examples of symmetric coefficients that treat positive matches (a) and negative matches (d) in the same way. + +![BinarySimilarityMeasures](/home/rozek/Documents/Spring2018/Cluster Analysis/BinarySimilarityMeasures.png) + +### Similarity Measures for Categorical Data with More Than Two Levels + +Categorical data where the variables have more than two levels (for example, eye color) could be dealt with in a similar way to binary data, with each level of a variable being regarded as a single binary variable. + +This is not an attractive approach, however, simply because of the large number of ‘negative’ matches which will inevitably be involved. + +A superior method is to allocate a score of zero or one to each variable depending on whether the two observations are the same on that variable. These scores are then averaged over all p variables to give the required similarity coefficient as +$$ +s_{ij} = \frac{1}{p}\sum_{k = 1}^p{s_{ik}} +$$ + +### Dissimilarity and Distance Measures for Continuous Data + +A **metric** on a set $X$ is a distance function +$$ +d : X \times X \to [0, \infty) +$$ +where $[0, \infty)$ is the set of non-negative real numbers and for all $x, y, z \in X$, the following conditions are satisfied + +1. $d(x, y) \ge 0$ non-negativity or separation axiom + 1. $d(x, y) = 0 \iff x = y$ identity of indiscernibles +2. $d(x, y) = d(y, x)$ symmetry +3. $d(x, z) \le d(x, y) + d(y, z)$ subadditivity or triangle inequality + +Conditions 1 and 2 define a positive-definite function + +All distance measures are formulated so as to allow for differential weighting of the quantitative variables $w_k$ denotes the nonnegative weights of $p$ variables + +![continuousdissimilaritymeasures](/home/rozek/Documents/Spring2018/Cluster Analysis/continuousdissimilaritymeasures.png) + +Proposed dissimilarity measures can be broadly divided into distance measures and correlation-type measures. + +#### Distance Measures + +#####$L^p$ Space + +The Minkowski distance is a metric in normed vector space which can be considered as a generalization of both the Euclidean distance and the Manhattan distance +$$ +D(X, Y) = (\sum_{i = 1}^n{w_i^p|x_i - y_i|^p})^{\frac{1}{p}} +$$ +This is a metric for $p > 1$ + +######Manhattan Distance + +This is the case in the Minkowski distance when $p = 1$ +$$ +d(X, Y) = \sum_{i = 1}^n{w_i|x_i - y_i|} +$$ +Manhattan distance depends on the rotation of the coordinate system, but does not depend on its reflection about a coordinate axis or its translation +$$ +d(x, y) = d(-x, -y) +$$ + +$$ +d(x, y) = d(x + a, y + a) +$$ + +Shortest paths are not unique in this metric + +######Euclidean Distance + +This is the case in the Minkowski distance when $p = 2$. The Euclidean distance between points X and Y is the length of the line segment connection them. +$$ +d(X, Y) = \sqrt{\sum_{i = 1}^n{w_i^2(x_i - y_i)^2}} +$$ +There is a unique path in which it has the shortest distance. This distance metric is also translation and rotation invariant + +######Squared Euclidean Distance + +The standard Euclidean distance can be squared in order to place progressively greater weight on objects that are farther apart. In this case, the equation becomes +$$ +d(X, Y) = \sum_{i = 1}^n{w_i^2(x_i - y_i)^2} +$$ +Squared Euclidean Distance is not a metric as it does not satisfy the [triangle inequality](https://en.wikipedia.org/wiki/Triangle_inequality), however, it is frequently used in optimization problems in which distances only have to be compared. + +######Chebyshev Distance + +The Chebyshev distance is where the distance between two vectors is the greatest of their differences along any coordinate dimension. + +It is also known as **chessboard distance**, since in the game of [chess](https://en.wikipedia.org/wiki/Chess) the minimum number of moves needed by a [king](https://en.wikipedia.org/wiki/King_(chess)) to go from one square on a [chessboard](https://en.wikipedia.org/wiki/Chessboard) to another equals the Chebyshev distance +$$ +d(X, Y) = \lim_{p \to \infty}{(\sum_{i = 1}^n{|x_i - y_i|^p})}^\frac{1}{p} +$$ + +$$ += max_i(|x_i - y_i|) +$$ + +Chebyshev distance is translation invariant + +##### Canberra Distance Measure + +The Canberra distance (D4) is a weighted version of the $L_1$ Manhattan distance. This measure is very sensitive to small changes close to $x_{ik} = x_{jk} = 0$. + +It is often regarded as a generalization of the dissimilarity measure for binary data. In this context the measure can be divided by the number of variables, $p$, to ensure a dissimilarity coefficient in the interval $[0, 1]$ + +It can then be shown that this measure for binary variables is just one minus the matching coefficient. + +### Correlation Measures + +It has often been suggested that the correlation between two observations can be used to quantify the similarity between them. + +Since for correlation coefficients we have that $-1 \le \phi_{ij} \le 1$ with the value ‘1’ reflecting the strongest possible positive relationship and the value ‘-1’ the strongest possible negative relationship, these coefficients can be transformed into dissimilarities, $d_{ij}$, within the interval $[0, 1]$ + +The use of correlation coefficients in this context is far more contentious than its noncontroversial role in assessing the linear relationship between two variables based on $n$ observations. + +When correlations between two individuals are used to quantify their similarity the rows of the data matrix are standardized, not its columns. + +**Disadvantages** + +When variables are measured on different scales the notion of a difference between variable values and consequently that of a mean variable value or a variance is meaningless. + +In addition, the correlation coefficient is unable to measure the difference in size between two observations. + +**Advantages** + +However, the use of a correlation coefficient can be justified for situations where all of the variables have been measured on the same scale and precise values taken are important only to the extent that they provide information about the subject's relative profile + +Example: In classifying animals or plants, the absolute size of the organisms or their parts are often less important than their shapes. In such studies the investigator requires a dissimilarity coefficient that takes the value zero if and only if two individuals' profiles are multiples of each other. The angular separation dissimilarity measure has this property. + +**Further considerations** + +The Pearson correlation is sensitive to outliers. This has prompted a number of suggestions for modifying correlation coefficients when used as similarity measures; for example, robust versions of correlation coefficients such as *jackknife correlation* or altogether more general association coefficients such as *mutual information distance measure* + +####Mahalanobis (Maximum) Distance [Not between 2 observations] + +Mahalanobis distance is a measure of distance between a point P and a distribution D. It is a multi-dimensional generalization of the idea of measuring how many standard deviations away P is from the mean of D + +Mahalanobis distance is unitless and scale-invariant and takes into account the correlations of the data set +$$ +D(\vec{x}) = \sqrt{(\vec{x} - \vec{\mu})^T S^{-1}(\vec{x}-\vec{\mu})} +$$ +Where $\mu$ is a set of mean observations and $S$ is the covariance matrix + +If the covariance matrix is diagonal then the resulting distance measure is called a normalized Euclidean distance. +$$ +d(\vec{x}, \vec{y}) = \sqrt{\sum_{i = 1}^N{\frac{(x_i - y_i)^2}{s^2_i}}} +$$ +Where $s_i$ is the standard deviation of the $x_i$ and $y_i$ over the sample set + +####Discrete Metric + +This metric describes whether or not two observations are equivalent +$$ +\rho(x, y) = \begin{cases} + 1 & x \not= y \\ + 0 & x = y + \end{cases} +$$ + +## Similarity Measures for Data Containing both Continuous and Categorical Variables + +There are a number of approaches to constructing proximities for mixed-mode data, that is, data in which some variables are continuous and some categorical. + +1. Dichotomize all variables and use a similarity measure for binary data +2. Rescale all the variables so that they are on the same scale by replacing variable values by their ranks among the objects and then using a measure for continuous data +3. Construct a dissimilarity measure for each type of variable and combine these, either with or without differential weighting into a single coefficient. + +Most general-purpose statistical software implement a number of measurs for converting two-mode data matrix into a one-mode dissimilarity matrix. + +R has `cluster`, `clusterSim`, or `proxy` + +### Proximity Measures for Structured Data + +We'll be looking at data that consists of repeated measures of the same outcome variable but under different conditions. + +The simplest and perhaps most commonly used approach to exploiting the reference variable is in the construction of a reduced set of relevant summaries per object which are then used as the basis for defining object similarity. + +Here we will look at some approaches for choosing summary measures and resulting proximity measures for the most frequently encountered reference vectors (e.g. time, experimental condition, and underlying factor) + +Structured data arise when the variables can be assumed to follow a known *factor model*. Under *confirmatory factor analysis model* each variable or item can be allocated to one of a set of underlying factors or concepts. The factors cannot be observed directly but are 'indicated' by a number of items that are all measured on the same scale. + +Note that the summary approach, while typically used with continuous variables, is not limited to variables on an interval scale. The same principles can be applied to dealing with categorical data. The difference is that summary measures now need to capture relevant aspects of the distribution of categorical variables over repeated measures. + +Rows of **$X$** which represent ordered lists of elements, that is all the variables provide a categorical outcome and these variables can be aligned in one dimension, are more generally referred to as *sequences*. *Sequence analysis* is an area of research that centers on problems of events and actions in their temporal context and includes the measurements of similarities between sequences. + +The most popular measure of dissimilarity between two sequences is the Levenhstein distance and counts the minimum number of operations needed to transform one sequence of categories into another, where an operation is an insertion, a deletion, or a substitution of a single category. Each operation may be assigned a penalty weight (a typical choice would be to give double the penalty to a substitution as opposed to an insertion or deletion. The measure is sometimes called the 'edit distance' due to its application in spell checkers. + +Optimal matching algorithms (OMAs) need to be employed to find the minimum number of operations required to match one sequence to another. One such algorithm for aligning sequences is the Needleman-Wunsch algorithm, which is commonly used in bioinformatics to align proteins. + +The *Jary similarity measure* is a related measure of similarity between sequences of categories often used to delete duplicates in the area of record linkage. + +## Inter-group Proximity Measures + +In clustering applications, it becomes necessary to consider how to measure the proximity between groups of individuals. + +1. The proximity between two groups might be defined by a suitable summary of the proximities between individuals from either group +2. Each group might be described by a representative observation by choosing a suitable summary statistic for each variable, and the inter group proximity defined as the proximity between the representative observations. + +### Inter-group Proximity Derived from the Proximity Matrix + +For deriving inter-group proximities from a matrix of inter-individual proximities, there are a variety of possibilities + +- Take the smallest dissimilarity between any two individuals, one from each group. This is referred to as *nearest-neighbor distance* and is the basis of the clustering technique known as *single linkage* +- Define hte intergroup distance as the largest distance between any two individuals, one from each group. This is known as the *furthest-neighbour distance* and constitute the basis of *complete linkage* cluster method. +- Define as the average dissimiliarity between individuals from both groups. Such a measure is used in *group average clustering* + +### Inter-group Proximity Based on Group Summaries for Continuous Data + +One method for constructing inter-group dissimilarity measures for continuous data is to simply substitute group means (also known as the centroid) for the variable values in the formulae for inter-individual measures + +More appropriate, however, might be measures which incorporate in one way or another, knowledge of within-group variation. One possibility is to use Mahallanobis's generalized distance. + +####Mahalanobis (Maximum) Distance + +Mahalanobis distance is a measure of distance between a point P and a distribution D. It is a multi-dimensional generalization of the idea of measuring how many standard deviations away P is from the mean of D + +Mahalanobis distance is unitless and scale-invariant and takes into account the correlations of the data set +$$ +D(\vec{x}) = \sqrt{(\vec{x} - \vec{\mu})^T S^{-1}(\vec{x}-\vec{\mu})} +$$ +Where $\mu$ is a set of mean observations and $S$ is the covariance matrix + +If the covariance matrix is diagonal then the resulting distance measure is called a normalized Euclidean distance. +$$ +d(\vec{x}, \vec{y}) = \sqrt{\sum_{i = 1}^N{\frac{(x_i - y_i)^2}{s^2_i}}} +$$ +Where $s_i$ is the standard deviation of the $x_i$ and $y_i$ over the sample set + +Thus, the Mahalanobis distance incraeses with increasing distances between the two group centers and with decreasing within-group variation. + +By also employing within-group correlations, the Mahalanobis distance takes account the possibly non-spherical shapes of the groups. + +The use of Mahalanobis implies that the investigator is willing to **assume** that the covariance matrices are at least approximately the same in the two groups. When this is not so, this measure is an inappropriate inter-group measure. Other alternatives exist such as the one proposed by Anderson and Bahadur + +equation + +Another alternative is the *normal information radius* suggested by Jardine and Sibson + +equation + +### Inter-group Proximity Based on Group Summaries for Categorical Data + +Approaches for measuring inter-group dissimilarities between groups of individuals for which categorical variables have been observed have been considered by a number of authors. Balakrishnan and Sanghvi (1968), for example, proposed a dissimilarity index of the form + +![equation](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczMwL2UwLXMzL2VpL3RtYTBjMGdzY2QwLmkyLWdtaWY-) + +where $p_{Akl}$ and $p_{Bkl}$ are the proportions of the lth category of the kth variable in group A and B respectively, ![img](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczNmL2VnMi8zbGVpL3RtYTBjbmdzaWUuMGlpbg--), ck + 1 is the number of categories for the kth variable and p is the number of variables. + +Kurczynski (1969) suggested adapting the generalized Mahalanobis distance, with categorical variables replacing quantitative variables. In its most general form, this measure for inter-group distance is given by + +![equation](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczMxL2UwLXMzL2VpL3RtYTBjMGdzY2QwLmkyLWdtaWY-) + +where ![img](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczNmL2VnMy8zbGVpL3RtYTBjbmdzaWUuMGlpbg--) contains sample proportions in group A and ![img](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczNmL2VnNC8zbGVpL3RtYTBjbmdzaWUuMGlpbg--) is defined in a similar manner, and ![img](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczNmL2VnNS8zbGVpL3RtYTBjbmdzaWUuMGlpbg--) is the m × m common sample covariance matrix, where ![img](http://proquest.safaribooksonline.com.ezproxy.umw.edu/getfile?item=cjlhZWEzNDg0N2R0cGMvaS9zMG1nODk0czcvN3MwczNmL2VnNi8zbGVpL3RtYTBjbmdzaWUuMGlpbg--). + +## Weighting Variables + +To weight a variable means to give it greater or lesser importance than other variables in determining the proximity between two objects. + +The question is 'How should the weights be chosen?' Before we discuss this question, it is important to realize that the selection of variables for inclusion into the study already presents a form of weighting, since the variables not included are effectively being given the weight $0$. + +The weights chosen for the variables reflect the importance that the investigator assigns the variables for the classification task. + +There are several approaches to this + +- Authors obtain perceived dissimilarities between selected objects, they then model the dissimilarities using the underlying variables and weights that indicate their relative importance. The weights that best fit the perceived dissimilarities are then chosen. +- Define the weights to be inversely proportion to some measure of variability in this variable. This choice of weights implies that the importance of a variable decreases when its variability increases. + - For a continous variable, the most commonly emplyed weight is either the reciprocal of its standard deviation or the reciprocal of its range + - Employing variability weights is equivalent to what is commonly referred to as *standardizing* the variables. +- Construct weights from the data matrix using *variable section*. In essence, such procedures proceed in an iterative fashion to identify variables which, when contributing to a cluster algorithm, lead to internally cohesive and externally isolated clusters and, when clustered singly, produce reasonable agreement. + +The second approach assumed the importance of a variable to be inversely proportional to the total variability of that variable. The total variability of a variable comprises variation both within and between groups which may exist within the set of individuals. The aim of cluster analysis is typically to identify such groups. Hence it can be argued that the importance of a variable should not be reduced because of between-group variation (on the contrary, one might wish to assign more importance to a variable that shows larger between-group variation.) + +Gnanadesikan et al. (1995) assessed the ability of squared distance functions based on data-determined weights, both those described above and others, to recover groups in eight simulated and real continuous data sets in a subsequent cluster analysis. Their main findings were: + +1. Equal weights, (total) standard deviation weights, and range weights were generally ineffective, but range weights were preferable to standard deviation weights. +2. Weighting based on estimates of within-cluster variability worked well overall. +3. Weighting aimed at emphasizing variables with the most potential for identifying clusters did enhance clustering when some variables had a strong cluster structure. +4. Weighting to optimize the fitting of a hierarchical tree was often even less effective than equal weighting or weighting based on (total) standard deviations. +5. Forward variable selection was often among the better performers. (Note that all-subsets variable selection was not assessed at the time.) + +## Standardization + +In many clustering applications, the variables describing the objects to be clustered will not be measured in the same units. A number of variability measures have been used for this purpose + +- When standard deviations calculated from the complete set of objects to be clustered are used, the technique is often referred to as *auto-scaling, standard scoring, or z-scoring*. +- Division by the median absolute deviations or by the ranges. + +The second is shown to outperform auto-scaling in many clustering applications. As pointed out in the previous section, standardization of variables to unit variance can be viewed as a special case of weighting. + +## Choice of Proximity Measure + +Firstly, the nature of the data should strongly influence the choice of the proximity measure. + +Next, the choice of measure should depend on the scale of the data. Similarity coefficients should be used when the data is binary. For continuous data, distance of correlation-type dissimilarity measure should be used according to whether 'size' or 'shape' of the objects is of interest. + +Finally, the clustering method to be used might have some implications for the choice of the coefficient. For example, making a choice between several proximity coefficients with similar properties which are also known to be monotonically related can be avoided by employing a cluster method that depends only on the ranking of the proximities, not their absolute values. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec10-1.md b/content/research/clusteranalysis/notes/lec10-1.md new file mode 100644 index 0000000..a984b48 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec10-1.md @@ -0,0 +1,46 @@ +# Silhouette + +This technique validates the consistency within clusters of data. It provides a succinct graphical representation of how well each object lies in its cluster. + +The silhouette ranges from -1 to 1 where a high value indicates that the object is consistent within its own cluster and poorly matched to neighboring clustesr. + +A low or negative silhouette value can mean that the current clustering configuration has too many or too few clusters. + +## Definition + +For each datum $i$, let $a(i)$ be the average distance of $i$ with all other data within the same cluster. + +$a(i)$ can be interpreted as how well $i$ is assigned to its cluster. (lower values mean better agreement) + +We can then define the average dissimilarity of point $i$ to a cluster $c$ as the average distance from $i$ to all points in $c$. + +Let $b(i)$ be the lowest average distance of $i$ to all other points in any other cluster in which i is not already a member. + +The cluster with this lowest average dissimilarity is said to be the neighboring cluster of $i$. From here we can define a silhouette: +$$ +s(i) = \frac{b(i) - a(i)}{max\{a(i), b(i)\}} +$$ +The average $s(i)$ over all data of a cluster is a measure of how tightly grouped all the data in the cluster are. A silhouette plot may be used to visualize the agreement between each of the data and its cluster. + +![img](https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Silhouette-plot-orange.png/800px-Silhouette-plot-orange.png) + +### Properties + +Recall that $a(i)$ is a measure of how dissimilar $i$ is to its own cluster, a smaller value means that it's in agreement to its cluster. For $s(i)$ to be close to 1, we require $a(i) << b(i)$ . + +If $s(i)$ is close to negative one, then by the same logic we can see that $i$ would be more appropriate if it was clustered in its neighboring cluster. + +$s(i)$ near zero means that the datum is on the border of two natural clusters. + +## Determining the number of Clusters + +This can also be used in helping to determine the number of clusters in a dataset. The ideal number of cluster is one that produces the highest silhouette value. + +Also a good indication that one has too many clusters is if there are clusters with the majority of observations being under the mean silhouette value. + +https://kapilddatascience.wordpress.com/2015/11/10/using-silhouette-analysis-for-selecting-the-number-of-cluster-for-k-means-clustering/ + +![plot_kmeans_silhouette_analysis_004](https://kapilddatascience.files.wordpress.com/2015/11/plot_kmeans_silhouette_analysis_004.png?w=660&h=257) + + + diff --git a/content/research/clusteranalysis/notes/lec10-2.md b/content/research/clusteranalysis/notes/lec10-2.md new file mode 100644 index 0000000..ec85b61 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec10-2.md @@ -0,0 +1,54 @@ + # Centroid-based Clustering + +In centroid-based clustering, clusters are represented by some central vector which may or may not be a member of the dataset. In practice, the number of clusters is fixed to $k$ and the goal is to solve some sort of optimization problem. + +The similarity of two clusters is defined as the similarity of their centroids. + +This problem is computationally difficult so there are efficient heuristic algorithms that are commonly employed. These usually converge quickly to a local optimum. + +## K-means clustering + +This aims to partition $n$ observations into $k$ clusters in which each observation belongs to the cluster with the nearest mean which serves as the centroid of the cluster. + +This technique results in partitioning the data space into Voronoi cells. + +### Description + +Given a set of observations $x$, k-means clustering aims to partition the $n$ observations into $k$ sets $S$ so as to minimize the within-cluster sum of squares (i.e. variance). More formally, the objective is to find +$$ +argmin_s{\sum_{i = 1}^k{\sum_{x \in S_i}{||x-\mu_i||^2}}}= argmin_{s}{\sum_{i = 1}^k{|S_i|Var(S_i)}} +$$ +where $\mu_i$ is the mean of points in $S_i$. This is equivalent to minimizing the pairwise squared deviations of points in the same cluster +$$ +argmin_s{\sum_{i = 1}^k{\frac{1}{2|S_i|}\sum_{x, y \in S_i}{||x-y||^2}}} +$$ + +### Algorithm + +Given an initial set of $k$ means, the algorithm proceeds by alternating between two steps. + +**Assignment step**: Assign each observation to the cluster whose mean has the least squared euclidean distance. + +- Intuitively this is finding the nearest mean +- Mathematically this means partitioning the observations according to the Voronoi diagram generated by the means + +**Update Step**: Calculate the new means to be the centroids of the observations in the new clusters + +The algorithm is known to have converged when assignments no longer change. There is no guarantee that the optimum is found using this algorithm. + +The result depends on the initial clusters. It is common to run this multiple times with different starting conditions. + +Using a different distance function other than the squared Euclidean distance may stop the algorithm from converging. + +### Initialization methods + +Commonly used initialization methods are Forgy and Random Partition. + +**Forgy Method**: This method randomly chooses $k$ observations from the data set and uses these are the initial means + +This method is known to spread the initial means out + +**Random Partition Method**: This method first randomly assigns a cluster to each observation and then proceeds to the update step. + +This method is known to place most of the means close to the center of the dataset. + diff --git a/content/research/clusteranalysis/notes/lec10-3.md b/content/research/clusteranalysis/notes/lec10-3.md new file mode 100644 index 0000000..c68221f --- /dev/null +++ b/content/research/clusteranalysis/notes/lec10-3.md @@ -0,0 +1,18 @@ +# Voronoi Diagram + +A Voronoi diagram is a partitioning of a plan into regions based on distance to points in a specific subset of the plane. + +The set of points (often called seeds, sites, or generators) is specified beforehand, and for each seed there is a corresponding region consisting of all points closer to that seed than any other. + +Different metrics may be used and often result in different Voronoi diagrams + +**Euclidean** + +![](https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Euclidean_Voronoi_diagram.svg/382px-Euclidean_Voronoi_diagram.svg.png) + +**Manhattan** + +![](https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Manhattan_Voronoi_Diagram.svg/382px-Manhattan_Voronoi_Diagram.svg.png) + + + diff --git a/content/research/clusteranalysis/notes/lec11-1.md b/content/research/clusteranalysis/notes/lec11-1.md new file mode 100644 index 0000000..99473f2 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec11-1.md @@ -0,0 +1,18 @@ +# K-means++ + +K-means++ is an algorithm for choosing the initial values or seeds for the k-means clustering algorithm. This was proposed as a way of avoiding the sometimes poor clustering found by a standard k-means algorithm. + +## Intuition + +The intuition behind this approach involves spreading out the $k$ initial cluster centers. The first cluster center is chosen uniformly at random from the data points that are being clustered, after which each subsequent cluster center is chosen from the remaining data points with probability proportional to its squared distance from the point's closest existing cluster center. + +## Algorithm + +The exact algorithm is as follows + +1. Choose one center uniformly at random from among data points +2. For each data point $x$, compute $D(x)$, the distance between $x$ and the nearest center that has already been chosen. +3. Choose one new data point at random as a new center, using a weighted probability distribution where a point $x$ is chosen with probability proporitonal to $D(x)^2$ +4. Repeat steps 2 and 3 until $k$ centers have been chosen +5. Now that the initial centers have been chosen, proceed using standard k-means clustering + diff --git a/content/research/clusteranalysis/notes/lec11-2.md b/content/research/clusteranalysis/notes/lec11-2.md new file mode 100644 index 0000000..e93639b --- /dev/null +++ b/content/research/clusteranalysis/notes/lec11-2.md @@ -0,0 +1,52 @@ +# K-Medoids + +A medoid can be defined as the object of a cluster whose average dissimilarity to all the objects in the cluster is minimal. + +The K-medoids algorithm is related to k-means and the medoidshift algorithm. Both the k-means and k-medoids algorithms are partition and both attempt to minimize the distance between points in the cluster to it's center. In contrast to k-means, it chooses data points as centers and uses the Manhattan Norm to define the distance between data points instead of the Euclidean. + +This method is known to be more robust to noise and outliers compared to k-means since it minimizes the sum of pairwise dissimilarities instead of the sum of squared Euclidean distances. + +## Algorithms + +There are several algorithms that have been created as an optimization to an exhaustive search. In this section, we'll discuss PAM and Voronoi iteration method. + +### Partitioning Around Medoids (PAM) + +1. Select $k$ of the $n$ data points as medoids +2. Associate each data point to the closes medoid +3. While the cost of the configuration decreases: + 1. For each medoid $m$, for each non-medoid data point $o$: + 1. Swap $m$ and $o$, recompute the cost (sum of distances of points to their medoid) + 2. If the total cost of the configuration increased in the previous step, undo the swap + + + +### Voronoi Iteration Method + +1. Select $k$ of the $n$ data points as medoids +2. While the cost of the configuration decreases + 1. In each cluster, make the point that minimizes the sum of distances within the cluster the medoid + 2. Reassign each point to the cluster defined by the closest medoid determined in the previous step. + + + +### Clustering Large Applications (CLARA + +This is a variant of the PAM algorithm that relies on the sampling approach to handle large datasets. The cost of a particular cluster configuration is the mean cost of all the dissimilarities. + + + +## R Implementations + +Both PAM and CLARA are defined in the `cluster` package in R. + +```R +clara(x, k, metric = "euclidean", stand = FALSE, samples = 5, + sampsize = min(n, 40 + 2 * k), trace = 0, medoids.x = TRUE, + keep.data = medoids.x, rngR = FALSE) +``` + +```R +pam(x, k, metric = "euclidean", stand = FALSE) +``` + diff --git a/content/research/clusteranalysis/notes/lec11-3.md b/content/research/clusteranalysis/notes/lec11-3.md new file mode 100644 index 0000000..20bbebb --- /dev/null +++ b/content/research/clusteranalysis/notes/lec11-3.md @@ -0,0 +1,19 @@ +# K-Medians + +This is a variation of k-means clustering where instead of calculating the mean for each cluster to determine its centroid we are going to calculate the median instead. + +This has the effect of minimizing error over all the clusters with respect to the Manhattan norm as opposed to the Euclidean squared norm which is minimized in K-means + +### Algorithm + +Given an initial set of $k$ medians, the algorithm proceeds by alternating between two steps. + +**Assignment step**: Assign each observation to the cluster whose median has the leas Manhattan distance. + +- Intuitively this is finding the nearest median + +**Update Step**: Calculate the new medians to be the centroids of the observations in the new clusters + +The algorithm is known to have converged when assignments no longer change. There is no guarantee that the optimum is found using this algorithm. + +The result depends on the initial clusters. It is common to run this multiple times with different starting conditions. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec12.md b/content/research/clusteranalysis/notes/lec12.md new file mode 100644 index 0000000..83dcee3 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec12.md @@ -0,0 +1,56 @@ +# Introduction to Density Based Clustering + +In density-based clustering, clusters are defined as areas of higher density than the remainder of the data sets. Objects in more sparse areas are considered to be outliers or border points. This helps discover clusters of arbitrary shape. + +## DBSCAN + +Given a set of points in space, it groups together points that are closely packed together while marking points that lie alone in low-density regions as outliers. + +### Preliminary Information + +- A point $p$ is a core point if at least k (often referred to as minPts) are within $\epsilon$ of it. Those points are said to be *directly reachable* from $p$. +- A point $q$ is directly reachable from $p$ if point $q$ is within distance $\epsilon$ from point $p$ and $p$ must be a core point +- A point $q$ is reachable from $p$ if there is a path $p_1, \dots, p_n$ with $p_1 = p$ and $p_n = q$ where each $p_{i + 1}$ is directly reachable from $p_i$. (All points on the path must be core points, with the possible exception of $q$) +- All points not reachable from any other points are outliers + +Non core points can be part of a cluster, but they form its "edge", since they cannot be used to reach more points. + +Reachability is not a symmetric relation since, by definition, no point may be reachable from a non-core point, regardless of distance. + +Two points $p$ and $q$ are density-connected if there is a point $o$ such that both $p$ and $q$ are reachable from $o$. Density-connectedness is symmetric. + +A cluster then satisfies two properties: + +1. All points within the cluster are mutually density-connected +2. If a point is density-reachable from any point of the cluster, it is part of the cluster as well. + + +### Algorithm + +1. Find the $\epsilon$ neighbors of every point, and identify the core points with more than $k$ neighbors. +2. Find the connected components of *core* points on the neighborhood graph, ignoring all non-core points. +3. Assign each non-core point to a nearby cluster if the cluster is an $\epsilon$ (eps) neighbor, otherwise assign it to noise. + +###Advantages + +- Does not require one to specify the number of clusters in the data +- Can find arbitrarily shaped clusters +- Has a notion of noise and is robust to outliers + +### Disadvantages + +- Not entirely deterministic: border points that are reachable from more than one cluster can be part of either cluster. +- The quality to DBSCAN depends on the distance measure used. +- Cannot cluster data sets well with large differences in densities. + +### Rule of Thumbs for parameters + +$k$: $k$ must be larger than $(D + 1)$ where $D$ is the number of dimensions in the dataset. Normally $k$ is chosen to be twice the number of dimensions. + +$\epsilon$: Ideally the $k^{th}$ nearest neighbors are at roughly the same distance. Plot the sorted distance of every point to it's $k^{th}$ nearest neighbor + + + +Example of Run Through + +https://www.cse.buffalo.edu/~jing/cse601/fa12/materials/clustering_density.pdf \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec2-1.md b/content/research/clusteranalysis/notes/lec2-1.md new file mode 100644 index 0000000..c7f420f --- /dev/null +++ b/content/research/clusteranalysis/notes/lec2-1.md @@ -0,0 +1,34 @@ +# Why use different distance measures? + +I made an attempt to find out in what situations people use different distance measures. Looking around in the Internet usually produces the results "It depends on the problem" or "I typically just always use Euclidean" + +Which as you might imagine, isn't a terribly useful answer. Since it doesn't give me any examples of which types of problems different distances solve. + +Therefore, let's think about it in a different way. What properties do different distance measures have that make them desirable? + +## Manhattan Advantages + +- The gradient of this function has a constant magnitude. There's no power in the formula +- Unusual values affect distances on Euclidean more since the difference is squared + +https://datascience.stackexchange.com/questions/20075/when-would-one-use-manhattan-distance-as-opposite-to-euclidean-distance + + + +## Mahalanobis Advantages + +Variables can be on different scales. The Mahalanobis formula has a built in variance-covariance matrix which allows you to rescale your variables to make distances of different variables more comparable. + +https://stats.stackexchange.com/questions/50949/why-use-the-mahalanobis-distance#50956 + + + +## Euclidean Disadvantages + +In higher dimensions, the points essentially become uniformly distant from one another. This is a problem observed in most distance metrics but it's more obvious with the Euclidean one. + +https://stats.stackexchange.com/questions/99171/why-is-euclidean-distance-not-a-good-metric-in-high-dimensions/ + + + +Hopefully in this course, we'll discover more properties as to why it makes sense to use different distance measures since it can have a impact on how our clusters are formed. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec2-2.md b/content/research/clusteranalysis/notes/lec2-2.md new file mode 100644 index 0000000..cb89f91 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec2-2.md @@ -0,0 +1,53 @@ +# Principal Component Analysis Pt. 1 + +## What is PCA? + +Principal component analysis is a statistical procedure that performs an orthogonal transformation to convert a set of variables into a set of linearly uncorrelated variables called principle components. + +Number of distinct principle components equals $min(\# Variables, \# Observations - 1)$ + +The transformation is defined in such a way that the first principle component has the largest possible variance explained in the data. + +Each succeeding component has the highest possible variance under the constraint of having to be orthogonal to the preceding components. + +PCA is sensitive to the relative scaling of the original variables. + +### Results of a PCA + +Results are discussed in terms of *component scores* which is the transformed variables and *loadings* which is the weight by which each original variable should be multiplied to get the component score. + +## Assumptions of PCA + +1. Linearity +2. Large variances are important and small variances denote noise +3. Principal components are orthogonal + +## Why perform PCA? + +- Distance measures perform poorly in high-dimensional space (https://stats.stackexchange.com/questions/256172/why-always-doing-dimensionality-reduction-before-clustering) +- Helps eliminates noise from the dataset (https://www.quora.com/Does-it-make-sense-to-perform-principal-components-analysis-before-clustering-if-the-original-data-has-too-many-dimensions-Is-it-theoretically-unsound-to-try-to-cluster-data-with-no-correlation) +- One initial cost to help reduce further computations + +## Computing PCA + +1. Subtract off the mean of each measurement type +2. Compute the covariance matrix +3. Take the eigenvalues/vectors of the covariance matrix + +## R Code + +```R +pcal = function(data) { + centered_data = scale(data) + covariance = cov(centered_data) + eigen_stuff = eigen(covariance) + sorted_indices = sort(eigen_stuff$values, + index.return = T, + decreasing = T)$ix + loadings = eigen_stuff$values[sorted_indices] + components = eigen_stuff$vectors[sorted_indices,] + combined_list = list(loadings, components) + names(combined_list) = c("Loadings", "Components") + return(combined_list) +} +``` \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec4-2.md b/content/research/clusteranalysis/notes/lec4-2.md new file mode 100644 index 0000000..1cbad20 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec4-2.md @@ -0,0 +1,24 @@ +# Revisiting Similarity Measures + +## Manhatten Distance + +An additional use case for Manhatten distance is when dealing with binary vectors. This approach, otherwise known as the Hamming distance, is the number of bits that are different between two binary vectors. + +## Ordinal Variables + +Ordinal variables can be treated as if they were on a interval scale. + +First, replace the ordinal variable value by its rank ($r_{if}$) Then map the range of each variable onto the interval $[0, 1]$ by replacing the $f_i$ where f is the variable and i is the object by +$$ +z_{if} = \frac{r_{if} - 1}{M_f - 1} +$$ +Where $M_f$ is the maximum rank. + +### Example + +Freshman = $0$ Sophmore = $\frac{1}{3}$ Junior = $\frac{2}{3}$ Senior = $1$ + +$d(freshman, senior) = 1$ + +$d(junior, senior) = \frac{1}{3}$ + diff --git a/content/research/clusteranalysis/notes/lec4-3.md b/content/research/clusteranalysis/notes/lec4-3.md new file mode 100644 index 0000000..b65b103 --- /dev/null +++ b/content/research/clusteranalysis/notes/lec4-3.md @@ -0,0 +1,40 @@ +# Cluster Tendency + +This is the assessment of the suitability of clustering. Cluster Tendency determines whether the data has any inherent grouping structure. + +This is a hard task since there are so many different definitions of clusters (portioning, hierarchical, density, graph, etc.) Even after fixing a cluster type, this is still hard in defining an appropriate null model for a data set. + +One way we can go about measuring cluster tendency is to compare the data against random data. On average, random data should not contain clusters. + +There are some clusterability assessment methods such as Spatial histogram, distance distribution and Hopkins statistic. + +## Hopkins Statistic + +Let $X$ be the set of $n$ data points in $d$ dimensional space. Consider a random sample (without replacement) of $m << n$ data points. Also generate a set $Y$ of $m$ uniformly randomly distributed data points. + +Now define two distance measures $u_i$ to be the distance of $y_i \in Y$ from its nearest neighbor in X and $w_i$ to be the distance of $x_i \in X$ from its nearest neighbor in X + +We can then define Hopkins statistic as +$$ +H = \frac{\sum_{i = 1}^m{u_i^d}}{\sum_{i = 1}^m{u_i^d} + \sum_{i =1}^m{w_i^d}} +$$ + +### Properties + +With this definition, uniform random data should tend to have values near 0.5, and clustered data should tend to have values nearer to 1. + +### Drawbacks + +However, data containing a single Gaussian will also score close to one. As this statistic measures deviation from a uniform distribution. Making this statistic less useful in application as real data is usually not remotely uniform. + + + +## Spatial Histogram Approach + +For this method, I'm not too sure how this works, but here are some key points I found. + +Divide each dimension in equal width bins, and count how many points lie in each of the bins and obtain the empirical joint probability mass function. + +Do the same for the randomly sampled data + +Finally compute how much they differ using the Kullback-Leibler (KL) divergence value. If it differs greatly than we can say that the data is clusterable. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec4.md b/content/research/clusteranalysis/notes/lec4.md new file mode 100644 index 0000000..984a04f --- /dev/null +++ b/content/research/clusteranalysis/notes/lec4.md @@ -0,0 +1,171 @@ +# Principal Component Analysis Part 2: Formal Theory + +##Properties of PCA + +There are a number of ways to maximize the variance of a principal component. To create an unique solution we should impose a constraint. Let us say that the sum of the square of the coefficients must equal 1. In vector notation this is the same as +$$ +a_i^Ta_i = 1 +$$ +Every future principal component is said to be orthogonal to all the principal components previous to it. +$$ +a_j^Ta_i = 0, i < j +$$ +The total variance of the $q$ principal components will equal the total variance of the original variables +$$ +\sum_{i = 1}^q {\lambda_i} = trace(S) +$$ +Where $S$ is the sample covariance matrix. + +The proportion of accounted variation in each principle component is +$$ +P_j = \frac{\lambda_j}{trace(S)} +$$ +From this, we can generalize to the first $m$ principal components where $m < q$ and find the proportion $P^{(m)}$ of variation accounted for +$$ +P^{(m)} = \frac{\sum_{i = 1}^m{\lambda_i}}{trace(S)} +$$ +You can think of the first principal component as the line of best fit that minimizes the residuals orthogonal to it. + +### What to watch out for + +As a reminder to the last lecture, *PCA is not scale-invariant*. Therefore, transformations done to the dataset before PCA and after PCA often lead to different results and possibly conclusions. + +Additionally, if there are large differences between the variances of the original variables, then those whose variances are largest will tend to dominate the early components. + +Therefore, principal components should only be extracted from the sample covariance matrix when all of the original variables have roughly the **same scale**. + +### Alternatives to using the Covariance Matrix + +But it is rare in practice to have a scenario when all of the variables are of the same scale. Therefore, principal components are typically extracted from the **correlation matrix** $R$ + +Choosing to work with the correlation matrix rather than the covariance matrix treats the variables as all equally important when performing PCA. + +## Example Derivation: Bivariate Data + +Let $R$ be the correlation matrix +$$ +R = \begin{pmatrix} +1 & r \\ +r & 1 +\end{pmatrix} +$$ +Let us find the eigenvectors and eigenvalues of the correlation matrix +$$ +det(R - \lambda I) = 0 +$$ + +$$ +(1-\lambda)^2 - r^2 = 0 +$$ + +$$ +\lambda_1 = 1 + r, \lambda_2 = 1 - r +$$ + +Let us remember to check the condition "sum of the principal components equals the trace of the correlation matrix": +$$ +\lambda_1 + \lambda_2 = 1+r + (1 - r) = 2 = trace(R) +$$ + +###Finding the First Eigenvector + +Looking back at the characteristic equation +$$ +Ra_1 = \lambda a_1 +$$ +We can get the following two formulas +$$ +a_{11} + ra_{12} = (1+r)a_{11} \tag{1} +$$ + +$$ +ra_{11} + a_{12} = (1 + r)a_{12} \tag{2} +$$ + +Now let us find out what $a_{11}$ and $a_{12}$ equal. First let us solve for $a_{11}$ using equation $(1)$ +$$ +ra_{12} = (1+r)a_{11} - a_{11} +$$ + +$$ +ra_{12} = a_{11}(1 + r - 1) +$$ + +$$ +ra_{12} = ra_{11} +$$ + +$$ +a_{12} = a_{11} +$$ + +Where $r$ does not equal $0$. + +Now we must apply the condition of sum squares +$$ +a_1^Ta_1 = 1 +$$ + +$$ +a_{11}^2 + a_{12}^2 = 1 +$$ + +Recall that $a_{12} = a_{11}$ +$$ +2a_{11}^2 = 1 +$$ + +$$ +a_{11}^2 = \frac{1}{2} +$$ + +$$ +a_{11} =\pm \frac{1}{\sqrt{2}} +$$ + +For sake of choosing a value, let us take the principal root and say $a_{11} = \frac{1}{\sqrt{2}}$ + +###Finding the Second Eigenvector + +Recall the fact that each subsequent eigenvector is orthogonal to the first. This means +$$ +a_{11}a_{21} + a_{12}a_{22} = 0 +$$ +Substituting the values for $a_{11}$ and $a_{12}$ calculated in the previous section +$$ +\frac{1}{\sqrt{2}}a_{21} + \frac{1}{\sqrt{2}}a_{22} = 0 +$$ + +$$ +a_{21} + a_{22} = 0 +$$ + +$$ +a_{21} = -a_{22} +$$ + +Since this eigenvector also needs to satisfy the first condition, we get the following values +$$ +a_{21} = \frac{1}{\sqrt{2}} , a_{22} = \frac{-1}{\sqrt{2}} +$$ + +### Conclusion of Example + +From this, we can say that the first principal components are given by +$$ +y_1 = \frac{1}{\sqrt{2}}(x_1 + x_2), y_2 = \frac{1}{\sqrt{2}}(x_1-x_2) +$$ +With the variance of the first principal component being given by $(1+r)$ and the second by $(1-r)$ + +Due to this, as $r$ increases, so does the variance explained in the first principal component. This in turn, lowers the variance explained in the second principal component. + +## Choosing a Number of Principal Components + +Principal Component Analysis is typically used in dimensionality reduction efforts. Therefore, there are several strategies for picking the right number of principal components to keep. Here are a few: + +- Retain enough principal components to account for 70%-90% of the variation +- Exclude principal components where eigenvalues are less than the average eigenvalue +- Exclude principal components where eigenvalues are less than one. +- Generate a Scree Plot + - Stop when the plot goes from "steep" to "shallow" + - Stop when it essentially becomes a straight line. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec5.md b/content/research/clusteranalysis/notes/lec5.md new file mode 100644 index 0000000..d6f874b --- /dev/null +++ b/content/research/clusteranalysis/notes/lec5.md @@ -0,0 +1,35 @@ +# Introduction to Connectivity Based Models + +Hierarchical algorithms combine observations to form clusters based on their distance. + +## Connectivity Methods + +Hierarchal Clustering techniques can be subdivided depending on the method of going about it. + +First there are two different methods in forming the clusters *Agglomerative* and *Divisive* + +Agglomerative is when you combine the n individuals into groups through each iteration + +Divisive is when you are separating one giant group into finer groupings with each iteration. + +Hierarchical methods are an irrevocable algorithm, once it joins or separates a grouping, it cannot be undone. As Kaufman and Rousseeuw (1990) colorfully comment: *"A hierarchical method suffers from the defect that it can never repair what was done in previous steps"*. + +It is the job of the statistician to decide when to stop the agglomerative or decisive algorithm, since having one giant cluster containing all observations or having each observation be a cluster isn't particularly useful. + +At different distances, different clusters are formed and are more readily represented using a **dendrogram**. These algorithms do not provide a unique solution but rather provide an extensive hierarchy of clusters that merge or divide at different distances. + +## Linkage Criterion + +Apart from the method of forming clusters, the user also needs to decide on a linkage criterion to use. Meaning, how do you want to optimize your clusters. + +Do you want to group based on the nearest points in each cluster? Nearest Neighbor Clustering + +Or do you want to based on the farthest observations in each cluster? Farthest neighbor clustering. + +![http://www.multid.se/genex/onlinehelp/clustering_distances.png](http://www.multid.se/genex/onlinehelp/clustering_distances.png) + +## Shortcomings + +This method is not very robust towards outliers, which will either show up as additional clusters or even cause other clusters to merge depending on the clustering method. + +As we go through this section, we will go into detail about the different linkage criterion and other parameters of this model. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec6.md b/content/research/clusteranalysis/notes/lec6.md new file mode 100644 index 0000000..2c03e9e --- /dev/null +++ b/content/research/clusteranalysis/notes/lec6.md @@ -0,0 +1,90 @@ +# Agglomerative Methods + +## Single Linkage + +First let us consider the single linkage (nearest neighbor) approach. The clusters can be found through the following algorithm + +1. Find the smallest non-zero distance +2. Group the two objects together as a cluster +3. Recompute the distances in the matrix by taking the minimum distances + - Cluster a,b -> c = min(d(a, c), d(b, c)) + +Single linkage can operate directly on a proximity matrix, the actual data is not required. + +A wonderful visual representation can be found in Everitt Section 4.2 + +## Centroid Clustering + +This is another criterion measure that requires both the data and proximity matrix. These are the following steps of the algorithm. Requires Euclidean distance measure to preserve geometric correctness + +1. Find the smallest non-zero distance +2. Group the two objects together as a cluster +3. Recompute the distances by taking the mean of the clustered observations and computing the distances between all of the observations + - Cluster a,b -> c = d(mean(a, b), c) + +## Complete Linkage + +This is like Single Linkage, except now we're taking the farthest distance. The algorithm can be adjusted to the following + +1. Find the smallest non-zero distance +2. Group the two objects together as a cluster +3. Recompute the distances in the matrix by taking the maximum distances + - Cluster a,b -> c = max(d(a, c), d(b, c)) + +##Unweighted Pair-Group Method using the Average Approach (UPGMA) + +In this criterion, we are no longer summarizing each cluster before taking distances, but instead comparing each observation in the cluster to the outside point and taking the average + +1. Find the smallest non-zero distance +2. Group the two objects together as a cluster +3. Recompute the distances in the matrix by taking the mean + - Cluster A: a,b -> c = $mean_{i = 0}(d(A_i, c))$ + +## Median Linkage + +This approach is similar to the UPGMA approach, except now we're taking the median instead of the mean + +1. Find the smallest non-zero distance +2. Group the two objects together as a cluster +3. Recompute the distances in the matrix by taking the median + - Cluster A: a,b -> c = $median_{i = 0}{(d(A_i, c))}$ + +## Ward Linkage + +This one I didn't look too far into but here's the description: With Ward's linkage method, the distance between two clusters is the sum of squared deviations from points to centroids. The objective of Ward's linkage is to minimize the within-cluster sum of squares. + +## When to use different Linkage Types? + +According to the following two stack overflow posts: https://stats.stackexchange.com/questions/195446/choosing-the-right-linkage-method-for-hierarchical-clustering and https://stats.stackexchange.com/questions/195456/how-to-select-a-clustering-method-how-to-validate-a-cluster-solution-to-warran/195481#195481 + +These are the following ways you can justify a linkage type. + +**Cluster metaphor**. *"I preferred this method because it constitutes clusters such (or such a way) which meets with my concept of a cluster in my particular project."* + +**Data/method assumptions**. *"I preferred this method because my data nature or format predispose to it."* + +**Internal validity**. *"I preferred this method because it gave me most clear-cut, tight-and-isolated clusters."* + +**External validity**. *"I preferred this method because it gave me clusters which differ by their background or clusters which match with the true ones I know."* + +**Cross-validity**. *"I preferred this method because it is giving me very similar clusters on equivalent samples of the data or extrapolates well onto such samples."* + +**Interpretation**. *"I preferred this method because it gave me clusters which, explained, are most persuasive that there is meaning in the world."* + +### Cluster Metaphors + +Let us explore the idea of cluster metaphors now. + +**Single Linkage** or **Nearest Neighbor** is a *spectrum* or *chain*. + +Since single linkage joins clusters by the shortest link between them, the technique cannot discern poorly separated clusters. On the other hand, single linkage is one of the few clustering methods that can delineate nonelipsodial clusters. + +**Complete Linkage** or **Farthest Neighbor** is a *circle*. + + **Between-Group Average linkage** (UPGMA) is a united *class + +**Centroid method** (UPGMC) is *proximity of platforms* (commonly used in politics) + +## Dendrograms + +A **dendrogram** is a tree diagram frequently used to illustrate the arrangement of the clusters produced by hierarchical clustering. It shows how different clusters are formed at different distance groupings. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec7.md b/content/research/clusteranalysis/notes/lec7.md new file mode 100644 index 0000000..2fe9e7a --- /dev/null +++ b/content/research/clusteranalysis/notes/lec7.md @@ -0,0 +1,74 @@ +# Divisive Methods Pt.1 + +Divisive methods work in the opposite direction of agglomerative methods. They take one large cluster and successively splits it. + +This is computationally demanding if all $2^{k - 1} - 1$ possible divisions into two sub-clusters of a cluster of $k$ objects are considered at each stage. + +While less common than Agglomerative methods, divisive methods have the advantage that most users are interested in the main structure in their data, and this is revealed from the outset of a divisive method. + +## Monothetic Divisive Methods + +For data consisting of $p$ **binary variables**, there is a computationally efficient method known as *monothetic divisive methods* available. + +Monothetic divisions divide clusters according to the presence or absence of each of the $p$ variables, so that at each stage, clusters contain members with certain attributes that are either all present or all absent. + +The term 'monothetic' refers to the use of a single variable on which to base the split on. *Polythetic* methods use all the variables at each stage. + +### Choosing the Variable to Split On + +The choice of the variable on which a split is made depends on optimizing a criterion reflecting either cluster homogeneity or association with other variables. + +This tends to minimize the number of splits that have to be made. + +An example of an homogeneity criterion is the information content $C$ + +This is defined with $p$ variables and $n$ objections where $f_k$ is the number of individuals with the $k$ attribute +$$ +C = pn\log{n}-\sum_{k = 1}^p{(f_k\log{f_k} - (n-f_k)\log{(n-f_k)})} +$$ + +### Association with other variables + +Recall that another way to split is based on the association with other variables. The attribute used at each step can be chosen according to its overall association with all attributes remaining at each step. + +This is sometimes termed *association analysis*. + +| | V1 | V2 | +| ---- | ---- | ---- | +| | 1 | 0 | +| 1 | a | b | +| 0 | c | d | + +####Common measures of association + +$$ +|ad-bc| \tag{4.6} +$$ + +$$ +(ad-bc)^2 \tag{4.7} +$$ + +$$ +\frac{(ad-bc)^2n}{(a+b)(a+c)(b+d)(c+d)} \tag{4.8} +$$ + +$$ +\sqrt{\frac{(ad-bc)^2n}{(a+b)(a+c)(b+d)(c+d)}} \tag{4.9} +$$ + +$$ +\frac{(ad-bc)^2}{(a+b)(a+c)(b+d)(c+d)} \tag{4.10} +$$ + +$(4.6)$ and $(4.7)$ have the advantage that there is no danger of computational problems if any marginal totals are near zero. + +The last three, $(4.8)$, $(4.9)$, $(4.10)$, are all related to the $\chi^2$ statistic, its square root, and the Pearson correlation coefficient respectively. + +### Advantages/Disadvantages of Monothetic Methods + +Appealing features of monothetic divisive methods are the easy classification of new members and the including of cases with missing values. + +A further advantage of monothetic divisive methods is that it is obvious which variables produce the split at any stage of the process. + +A disadvantage with these methods is that the possession of a particular attribute which is either rare or rarely found in combination with others may take an individual down a different path. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec8.md b/content/research/clusteranalysis/notes/lec8.md new file mode 100644 index 0000000..0c47d8e --- /dev/null +++ b/content/research/clusteranalysis/notes/lec8.md @@ -0,0 +1,48 @@ +# Divisive Methods Pt 2. + +Recall in the previous section that we spoke about Monothetic and Polythetic methods. Monothetic methods only looks at a single variable at a time while Polythetic looks at multiple variables simultaneously. In this section, we will speak more about polythetic divisive methods. + +## Polythetic Divisive Methods + +Polythetic methods operate via a distance matrix. + +This procedure avoids considering all possible splits by + +1. Finding the object that is furthest away from the others within a group and using that as a seed for a splinter group. +2. Each object is then considered for entry to that separate splinter group: any that are closer to the splinter group than the main group is moved to the splinter one. +3. The step is then repeated. + +This process has been developed into a program named `DIANA` (DIvisive ANAlysis Clustering) which is implemented in `R`. + +### Similarities to Politics + +This somewhat resembles a way a political party might split due to inner conflicts. + +Firstly, the most discontented member leaves the party and starts a new one, and then some others follow him until a kind of equilibrium is attained. + +## Methods for Large Data Sets + +There are two common hierarchical methods used for large data sets `BIRCH` and `CURE`. Both of these algorithms employ a pre-clustering phase in where dense regions are summarized, the summaries being then clustered using a hierarchical method based on centroids. + +### CURE + +1. `CURE` starts with a random sample of points and represents clusters by a smaller number of points that capture the shape of the cluster +2. Which are then shrunk towards the centroid as to dampen the effect of the outliers +3. Hierarchical clustering then operates on the representative points + +`CURE` has been shown to be able to cope with arbitrary-shaped clusters and in that respect may be superior to `BIRCH`, although it does require judgment as to the number of clusters and also a parameter which favors either more or less compact clusters. + +## Revisiting Topics: Cluster Dissimilarity + +In order to decide where clusters should be combined (for agglomerative), or where a cluster should be split (for divisive), a measure of dissimilarity between sets of observations is required. + +In most methods of hierarchical clustering this is achieved by a use of an appropriate + +- Metric (a measure of distance between pairs of observations) +- Linkage Criterion (which specifies the dissimilarities of sets as functions of pairwise distances observations in the sets) + +## Advantages of Hierarchical Clustering + +- Any valid measure of distance measure can be used +- In most cases, the observations themselves are not required, just hte matrix of distances + - This can have the advantage of only having to store a distance matrix in memory as opposed to a n-dimensional matrix. \ No newline at end of file diff --git a/content/research/clusteranalysis/notes/lec9-1.md b/content/research/clusteranalysis/notes/lec9-1.md new file mode 100644 index 0000000..d8bb4da --- /dev/null +++ b/content/research/clusteranalysis/notes/lec9-1.md @@ -0,0 +1,58 @@ +# CURE and TSNE + +##Clustering Using Representatives (CURE) + +Clustering using Representatives is a Hierarchical clustering technique in which you can represent a cluster using a **set** of well-scattered representative points. + +This algorithm has a parameter $\alpha$ which defines the factor of the points in which to shrink towards the centroid. + +CURE is known to be robust to outliers and able to identify clusters that have a **non-spherical** shape and size variance. + +The clusters with the closest pair of representatives are the clusters that are merged at each step of CURE's algorithm. + +This algorithm cannot be directly applied to large datasets due to high runtime complexity. Several enhancements were added to address this requirement + +- Random sampling: This involves a trade off between accuracy and efficiency. One would hope that the random sample they obtain is representative of the population +- Partitioning: The idea is to partition the sample space into $p$ partitions + +Youtube Video: https://www.youtube.com/watch?v=JrOJspZ1CUw + +Steps + +1. Pick a random sample of points that fit in main memory +2. Cluster sample points hierarchically to create the initial clusters +3. Pick representative point**s** + 1. For each cluster, pick $k$ representative points, as dispersed as possible + 2. Move each representative points to a fixed fraction $\alpha$ toward the centroid of the cluster +4. Rescan the whole dataset and visit each point $p$ in the data set +5. Place it in the "closest cluster" + 1. Closest as in shortest distance among all the representative points. + +## TSNE + +TSNE allows us to reduce the dimensionality of a dataset to two which allows us to visualize the data. + +It is able to do this since many real-world datasets have a low intrinsic dimensionality embedded within the high-dimensional space. + +Since the technique needs to conserve the structure of the data, two corresponding mapped points must be close to each other distance wise as well. Let $|x_i - x_j|$ be the Euclidean distance between two data points, and $|y_i - y_j|$ he distance between the map points. This conditional similarity between two data points is: +$$ +p_{j|i} = \frac{exp(-|x_i-x_j|^2 / (2\sigma_i^2))}{\sum_{k \ne i}{exp(-|x_i-x_k|^2/(2\sigma_i^2))}} +$$ +Where we are considering the **Gaussian distribution** surrounding the distance between $x_j$ from $x_i$ with a given variance $\sigma_i^2$. The variance is different for every point; it is chosen such that points in dense areas are given a smaller variance than points in sparse areas. + +Now the similarity matrix for mapped points are +$$ +q_{ij} = \frac{f(|x_i - x_j|)}{\sum_{k \ne i}{f(|x_i - x_k)}} +$$ +Where $f(z) = \frac{1}{1 + z^2}$ + +This has the same idea as the conditional similarity between two data points, except this is based on the **Cauchy distribution**. + +TSNE works at minimizing the Kullback-Leiber divergence between the two distributions $p_{ij}$ and $q_{ij}$ +$$ +KL(P || Q) = \sum_{i,j}{p_{i,j} \log{\frac{p_{ij}}{q_{ij}}}} +$$ +To minimize this score, gradient descent is typically performed +$$ +\frac{\partial KL(P||Q)}{\partial y_i} = 4\sum_j{(p_{ij} - q_{ij})} +$$ diff --git a/content/research/clusteranalysis/notes/lec9-2.md b/content/research/clusteranalysis/notes/lec9-2.md new file mode 100644 index 0000000..26c3dcf --- /dev/null +++ b/content/research/clusteranalysis/notes/lec9-2.md @@ -0,0 +1,72 @@ +# Cluster Validation + +There are multiple approaches to validating your cluster models + +- Internal Evaluation: This is when you summarize the clustering into a single score. For example, minimizing the the deviations from the centroids. +- External Evaluation: Minimizing the deviations from some known "labels" +- Manual Evaluation: A human expert decides whether or not it's good +- Indirect Evaluation: Evaluating the utility of clustering in its intended application. + +## Some Problems With These Evaluations + +Internal evaluation measures suffer form the problem that they represent functions that are objectives for many clustering algorithms. So of course the result of the clustering algorithm will be such that the objective would be minimized. + +External evaluation suffers from the fact that if we had labels to begin with then we wouldn't need to cluster. Practical applications of clustering occur usually when we don't have labels. On the other hand, possible labeling can reflect one possible partitioning of the data set. There could exist different, perhaps even better clustering. + +## Internal Evaluation + +We like to see a few qualities in cluster models + +- *Robustness*: Refers to the effects of errors in data or missing observations, and changes in the data and methods. +- *Cohesiveness*: Clusters should be compact or high high intra-cluster similarity. +- Clusters should be dissimilar to separate clusters. Should have low inter-cluster similarity +- *Influence*: We should pay attention to and try to control for the influence of certain observations on the overall cluster + +Let us focus on the second and third bullet point for now. Internal evaluation measures are best suited to get some insight into situations where one algorithm performs better than another, this does not imply that one algorithm produces more valid results than another. + +### Davies-Bouldin Index + +$$ +DB = \frac{1}{n}\sum_{i=1}^n{max_{j\ne i}{(\frac{\sigma_i + \sigma_j}{d(c_i,c_j)})}} +$$ + +Where $n$ is the number of clusters, $c$ indicates a centroid, and $\sigma$ represents the deviation from the centroid. + +Better clustering algorithms are indicated by smaller DB values. + +### Dunn Index + +$$ +D= \frac{min_{1\le i < j \le n}{d(i,j)}}{max_{1\le k \le n}{d^\prime(k)}} +$$ + +The Dunn index aims to identify dense and well-separated clusters. This is defined as the ratio between the minimal inter-cluster distance to maximal intra-cluster distance. + +High Dunn Index values are more desirable. + +###Bootstrapping + +In terms of robustness we can measure uncertainty in each of the individual clusters. This can be examined using a bootstrapping approach by Suzuki and Shimodaira (2006). The probability or "p-value" is the proportion of bootstrapped samples that contain the cluster. Larger p-values in this case indicate more support for the cluster. + +This is available in R via `Pvclust` + +### Split-Sample Validation + +One approach to assess the effects of perturbations of the data is by randomly dividing the data into two subsets and performing an analysis on each subset separately. This method was proposed by McIntyre and Blashfield in 1980; their method involves the following steps + +- Divide the sample in two and perform a cluster analysis on one of the samples + - Have a fixed rule for the number of clusters +- Determine the centroids of the clusters, and compute proximities between the objects in teh second sample and the centroids, classifying the objects into their nearest cluster. +- Cluster the second sample using the same methods as before and compare these two alternate clusterings using something like the *adjusted Rand index*. + +![Adjusted Index](https://wikimedia.org/api/rest_v1/media/math/render/svg/b1850490e5209123ab6e5b905495b4d5f9a1f661) + +## Influence of Individual Points + +Using internal evaluation metrics, you can see the impact of each point by doing a "leave one out" analysis. Here you evaluate the dataset minus one point for each of the points. If a positive difference is found, the point is regarded as a *facilitator*, whereas if it is negative then it is considered an *inhibitor*. once an influential inhibitor is found, the suggestion is to normally omit it from the clustering. + +## R Package + +`clValid` contains a variety of internal validation measures. + +Paper: https://cran.r-project.org/web/packages/clValid/vignettes/clValid.pdf \ No newline at end of file diff --git a/content/research/clusteranalysis/readings.md b/content/research/clusteranalysis/readings.md new file mode 100644 index 0000000..27cc818 --- /dev/null +++ b/content/research/clusteranalysis/readings.md @@ -0,0 +1,35 @@ +# Readings for Lectures of Cluster Analysis + +## Lecture 1 +Garson Textbook Chapter 3 + +## Lecture 2 +[A Tutorial on Principal Component Analysis](https://arxiv.org/pdf/1404.1100.pdf) + +## Lecture 3 +No Readings + +## Lecture 4 +An Introduction to Applied Multivariate Analysis with R by Brian Evveritt and Torsten Horthorn. + +Sections 3.0-3.9 Everitt + +## Lecture 5 + +Section 4.1 Everitt + +## Lecture 6 +Section 4.2 Everitt + +Applied Multivariate Statistical Analysis Johnson Section 12.3 + +[Linkage Methods for Cluster Observations](https://support.minitab.com/en-us/minitab/18/help-and-how-to/modeling-statistics/multivariate/how-to/cluster-observations/methods-and-formulas/linkage-methods/#mcquitty) + +## Lecture 7 +Section 4.3 Everitt + +## Lecture 8 +[Introduction to the TSNE Algorithm](https://www.oreilly.com/learning/an-illustrated-introduction-to-the-t-sne-algorithm) + +## Lecture 9 +Section 9.5 Everitt diff --git a/content/research/clusteranalysis/syllabus.md b/content/research/clusteranalysis/syllabus.md new file mode 100644 index 0000000..002dc8a --- /dev/null +++ b/content/research/clusteranalysis/syllabus.md @@ -0,0 +1,119 @@ +# Cluster Analysis Spring 2018 + +### Distance, Dimensionality Reduction, and Tendency + +- Distance + - Euclidean Distance + - Squared Euclidean Distance + - Manhattan Distance + - Maximum Distance + - Mahalanobis Distance +- Which distance function should you use? +- PCA +- Cluster Tendency + - Hopkins Statistic +- Scaling Data + +### Validating Clustering Models + +- Clustering Validation +- Cross Validation + +### Connectivity Models + +- Agglomerative Clustering + - Single Linkage Clustering + - Complete Linkage Clustering + - Unweighted Pair Group Method with Arithmetic Mean (If time permits) +- Dendrograms +- Divisive Clustering +- CURE (Clustering using REpresentatives) algorithm (If time permits) + +### Cluster Evaluation + +- Internal Evaluation + - Dunn Index + - Silhouette Coefficient + - Davies-Bouldin Index (If time permits) +- External Evaluation + - Rand Measure + - Jaccard Index + - Dice Index + - Confusion Matrix + - F Measure (If time permits) + - Fowlkes-Mallows Index (If time permits) + +### Centroid Models + +- Jenks Natural Breaks Optimization +- Voronoi Diagram +- K means clustering +- K medoids clustering +- K Medians/Modes clustering +- When to use K means as opposed to K medoids or K Medians? +- How many clusters should you use? +- Lloyd's Algorithm for Approximating K-means (If time permits) + +### Density Models + +- DBSCAN Density Based Clustering Algorithm +- OPTICS Ordering Points To Identify the Clustering Structure +- DeLi-Clu Density Link Clustering (If time permits) +- What should be your density threshold? + +### Analysis of Model Appropriateness + +- When do we use each of the models above? + +### Distribution Models (If time permits) + +- Fuzzy Clusters +- EM (Expectation Maximization) Clustering +- Maximum Likelihood Gaussian +- Probabilistic Hierarchal Clustering + + + + +## Textbooks + +Cluster Analysis 5th Edition + +- Authors: Brian S. Everitt, Sabine Landau, Morven Leese, Daniel Stahl +- ISBN-13: 978-0470749913 +- Cost: Free on UMW Library Site +- Amazon Link: https://www.amazon.com/Cluster-Analysis-Brian-S-Everitt/dp/0470749911/ref=sr_1_1?ie=UTF8&qid=1509135983&sr=8-1 +- Table of Contents: http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP002266.html + +Cluster Analysis: 2014 Edition (Statistical Associates Blue Book Series 24) + +- Author: David Garson +- ISBN: 978-1-62638-030-1 +- Cost: Free with Site Registration +- Website: http://www.statisticalassociates.com/clusteranalysis.htm + + + +## Schedule + +In an ideal world, the topics below I estimated being a certain time period for learning them. Of course you have more experience when it comes to how long it actually takes to learn these topics, so I'll leave this mostly to your discretion. + +**Distance, Dimensionality Reduction, and Tendency** -- 3 Weeks + +**Validating Cluster Models** -- 1 Week + +**Connectivity Models** -- 2 Weeks + +**Cluster Evaluation** -- 1 Week + +**Centroid Models** -- 3 Weeks + +**Density Models** -- 3 Weeks + +**Analysis of Model Appropriateness** -- 1 Week + +The schedule above accounts for 14 weeks, so there is a week that is free as a buffer. + +## Conclusion + +Creating this document got me really excited for this independent study. Feel free to give me feedback :) \ No newline at end of file diff --git a/content/research/deepreinforcementlearning.md b/content/research/deepreinforcementlearning.md new file mode 100644 index 0000000..da28df2 --- /dev/null +++ b/content/research/deepreinforcementlearning.md @@ -0,0 +1,22 @@ +--- +Title: Deep Reinforcement Learning +Description: Combining Reinforcement Learning with Deep Learning +--- + +In the Fall of 2019, I look at integrating demonstration data into a reinforcement learning algorithm in order to make it sample efficient. + +The results are positive and are heavily documented through the following: + +[Honors Thesis](/files/research/honorsthesis.pdf) + +[Honors Defense](/files/research/ExpeditedLearningInteractiveDemo.pptx) + +Thanks to my advisor Dr. Ron Zacharksi and my committee members for all their feedback on my work! + +In the spring of 2019, under the guidance of Dr. Ron Zacharski I practiced several of the modern techniques used in Reinforcement Learning today. + +I facilitated my learning by creating a [reinforcement learning library](https://github.com/brandon-rozek/rltorch) with implementations of several popular papers. ([Semi-Weekly Progress](weeklyprogress)) + +I also presented my research (which involved creating an algorithm) at my school's research symposium. ([Slides](/files/research/QEP.pptx)) ([Abstract](abstractspring2019)) + +In the summer of 2019, I became interested in having the interactions with the environment be in a separate process. This inspired two different implementations, [ZeroMQ](https://github.com/brandon-rozek/zerogym) and [HTTP](https://github.com/brandon-rozek/gymhttp). Given the option, you should use the ZeroMQ implementation since it contains less communication overhead. diff --git a/content/research/deepreinforcementlearning/WeeklyProgress.md b/content/research/deepreinforcementlearning/WeeklyProgress.md new file mode 100644 index 0000000..cc9d00c --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress.md @@ -0,0 +1,13 @@ +## Weekly Progress + +I didn't do the greatest job at writing a progress report every week but here on the page are the ones I did write. + +[January 29 2019](Jan29) + +[February 12 2019](Feb12) + +[February 25 2019](Feb25) + +[March 26 2019](Mar26) + +[April 2 2019](Apr2) \ No newline at end of file diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/1550549326169.png b/content/research/deepreinforcementlearning/WeeklyProgress/1550549326169.png new file mode 100644 index 0000000..b327209 Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/1550549326169.png differ diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/1550590562084.png b/content/research/deepreinforcementlearning/WeeklyProgress/1550590562084.png new file mode 100644 index 0000000..bb4e2d9 Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/1550590562084.png differ diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/1551158699648.png b/content/research/deepreinforcementlearning/WeeklyProgress/1551158699648.png new file mode 100644 index 0000000..b159eb4 Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/1551158699648.png differ diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/1551158802225.png b/content/research/deepreinforcementlearning/WeeklyProgress/1551158802225.png new file mode 100644 index 0000000..6385c07 Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/1551158802225.png differ diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/1551160033552.png b/content/research/deepreinforcementlearning/WeeklyProgress/1551160033552.png new file mode 100644 index 0000000..4ebb6b0 Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/1551160033552.png differ diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/Apr2.md b/content/research/deepreinforcementlearning/WeeklyProgress/Apr2.md new file mode 100644 index 0000000..33f81ca --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress/Apr2.md @@ -0,0 +1,25 @@ +# Progress Report for Week of April 2nd + +## Added Video Recording Capability to MinAtar environment + +You can now use the OpenAI Monitor Wrapper to watch the actions performed by agents in the MinAtar suite. (Currently the videos are in grayscale) + +Problems I had to solve: + +- How to represent the channels into a grayscale value +- Getting the tensor into the right format (with shape and dtype) +- Adding additional meta information that OpenAI expected + +## Progress Towards \#Exploration + +After getting nowhere trying to combine the paper on Random Network Distillation and Count-based exploration and Intrinsic Motivation, I turned the paper \#Exploration: A Study of Count-Based Exploration for Deep Reinforcement Learning. + +This paper uses the idea of an autoencoder to learn a smaller latent state representation of the input. We can then use this smaller representation as a hash and count states based on these hashes. + +Playing around with the ideas of autoencoders, I wanted a way to discretized my hash more than just what floating point precision allows. Of course this turns it into a non-differential function which I then tried turning towards Evolutionary methods to solve. Sadly the rate of optimization was drastically diminished using the Evolutionary approach. Therefore, my experiments for this week failed. + +I'll probably look towards implementing what the paper did for my library and move on to a different piece. + + + +Guru Indian: 3140 Cowan Blvd, Fredericksburg, VA 22401 \ No newline at end of file diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/Feb12.md b/content/research/deepreinforcementlearning/WeeklyProgress/Feb12.md new file mode 100644 index 0000000..2f419a1 --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress/Feb12.md @@ -0,0 +1,63 @@ +# Weekly Progress Feb 12 + +## Finished writing scripts for data collection + +- Playing a game now records + - Video + - State / Next-State as pixel values + - Action taken + - Reward Received + - Whether the environment is finished every turn +- Wrote scripts to gather and preprocess the demonstration data + - Now everything is standardized on the npy format. Hopefully that stays consistent for a while. + +## Wrote code to create an actor that *imitates* the demonstrator + +Tweaked the loss function to be a form of cross-entropy loss +$$ +loss = max(Q(s, a) + l(s,a)) - Q(s, a_E) +$$ +Where $l(s, a)$ is zero for the action the demonstrator took and positive elsewhere. + +Turns out, that as with a lot of deep learning applications, you need a lot of training data. So the agent currently does poorly on mimicking the performance of the demonstrator. + +### Aside : Pretraining with the Bellman Equation + +Based off the paper: + +Todd Hester, Matej Vecerik, Olivier Pietquin, arc Lanctot, Tom Schaul, Bilal Piot, Andrew Sendonaris, Gabriel Dulac-Arnold, Ian OsbandI, John Agapiou, Joel Z. Leibo, Audrunas Gruslys. **Learning from Demonstrations for Real World Reinforcement Learning** + + + +This paper had the demonstration not include include the $(state, action)$ pairs like I did, but also the $(next_state, reward, done)$ signals. This way, they can pretrain with both supervised loss and with the general Q-learning loss. + +That way, they can use the result of the pretraining as a starting ground for the actual training. The way I implemented it, I would first train an imitator which would then be used as the actor during the simulations from which we would collect data and begin training another net. + +## Prioritized Replay + +Instead of uniform sampling of experiences, we can sample by how surprised we were about the outcome of the Q-value loss. + +I had a previous implementation of this, but it was faulty, so I took the code from OpenAI baselines and integrated it with my library. + +It helps with games like Pong, because there are many states where the result is not surprising and inconsequential. Like when the ball is around the center of the field. + +## Schedulers + +There are some people who use Linear Schedulers to change the value of various parameters throughout training. + +I implemented it as an iterator in python and called *next* for each time the function uses the hyper-parameter. + +The two parameters I use schedulers in normally are: + +- Epsilon - Gradually decreases exploration rate +- Beta - Decreases the importance of the weights of experiences that get frequently sampled + + + +## Layer Norm + +"Reduces training by normalizes the activities of the neurons." + +Jimmy Lei Ba, Jamie Ryan Kiros, Geoffrey E. Hinton. **Layer Normalization.** + +It's nicely implemented in PyTorch already so I threw that in for each layer of the network. Reduces the average loss. \ No newline at end of file diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/Feb25.md b/content/research/deepreinforcementlearning/WeeklyProgress/Feb25.md new file mode 100644 index 0000000..5d125fe --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress/Feb25.md @@ -0,0 +1,117 @@ +# Weekly Progress for February 25th + +## Evolutionary Algorithms + +### Genetic Algorithm + +I worked towards implementing the Genetic Algorithm into PyTorch. I got a working implementation which operates like the following: + +Generate $n$ perturbations of the model by taking the tensors in the model dictionary and add some random noise to them. + +- Calculate the fitness of each model +- Keep the $k$ best survivors +- Sample (with replacement) $2(n - k)$ parents based on their fitness. (Higher fitness -> More likely to be sampled) + + - Easy way to do this is: $prob = fitness / sum(fitness)$ +- Split the parents in half to $parent1$ and $parent2$ +- Perform crossover in order to make children + + - For every tensor in the model dictionary + + - Find a point in where you want the split to happen + - Create a new tensor: the left part of the split comes from $parent1$, the other side from $parent2$ + - Mutate the child with $\epsilon$ probability + - Add random noise to the tensor + +Normally if you perform this algorithm with many iterations, your results start to converge towards a particular solution. + +The main issue with this algorithm is that you need to carry with you $n$ models of the environment throughout the entire training process. You also need to have a somewhat good definition of the bounds of which your weights and biases can be otherwise the algorithm might not converge to the true value. + +Due to these reasons, I didn't end up adding this functionality to RLTorch. + +### Evolutionary Strategies + +To combat these issues, I knocked into a paper by OpenAI Called "Evolutionary Strategies" + +Tim Salimans, Jonathan Ho, Xi Chen, Szymon Sidor, Ilya Sutskever. **Evolution Strategies as a Scalable Alternative to Reinforcement Learning** + +https://arxiv.org/abs/1703.03864 + +*This paper mostly describes the efforts made to make a certain evolutionary strategy scalable to many nodes. I ended up using only the algorithm from the paper and I didn't implement any of the scalable considerations.* + +The following code below explains the process for maximizing a simple function + +```python +white_noise = np.random.randn(population_size, *current_solution.shape) +noise = sigma * white_noise +candidate_solutions = current_solution + noise + +# Calculate fitness, mean shift, and scale +fitness_values = calculate_fitness(candidate_solutions) +fitness_values = (fitness_values - np.mean(fitness_values)) / (np.std(fitness_values) + np.finfo('float').eps) + +new_solution = current_solution + learning_rate * np.mean(white_noise.T * fitness_values, axis = 1) / sigma +``` + +To explain further, suppose you have a guess as to what the solution is. To generate new guesses, let us add random noise around our guess like the image below. + +![1551158699648](/home/rozek/Documents/Research/Deep RL/WeeklyProgress/1551158699648.png) + +Now calculate the fitness of all the points, let us represent that by the intensity of blue in the background, + +![1551158802225](/home/rozek/Documents/Research/Deep RL/WeeklyProgress/1551158802225.png) + +What ends up happening is that your new solution, the black square, will move towards the areas with higher reward. + +## Q-Evolutionary Policies + +**Motivation** + +So this brings up the point, why did I bother studying these algorithms? I ran into a problem when I was looking to implement the DDPG algorithm. Primarily that it required your action space to be continuous, which is not something I'm currently on. + +Then I thought, why can I not make it work with discrete actions? First let us recall the loss of a policy function under DDPG: +$$ +loss_\pi = -Q(s, \pi(s)) +$$ +For the discrete case, your Q-function is going to be a function of the state and output the values of each action taken under that state. In mathematical terms, +$$ +loss_\pi = -Q(s)[\pi(s)] +$$ +Indexing into another array, however, is not a differentiable function. Meaning I cannot then calculate $loss_\pi$ with respect to $\pi$. + +Evolutionary Strategies are non-gradient based methods. Meaning that I can bypass this restriction with the traditional methods. + +**How it works** + +Train your Value function with the typical DQN loss. + +Every 10 Value function updates, update the policy. This gives time for the Value function to stabilize so that the policy is not chasing suboptimal value functions. Update the policy according to the $loss_\pi$ written above. + +**Results** + +![1551160033552](/home/rozek/Documents/Research/Deep RL/WeeklyProgress//1551160033552.png) + +The orange line is the QEP performance + +Blue is DQN + +## Future Direction + +I would like to look back towards demonstration data and figure out a way to pretrain a QEP model. + +It's somewhat easy to think of a way to train the policy. Make it a cross-entropy loss with respect to the actions the demonstrator took. +$$ +loss_\pi = -\sum_{c=1}^M{y_{o,c}\ln{(p_{o,c})}} +$$ +Where $M$ is the number of classes, $y$ is the binary indicator for whether the correction classification was observed, and $p$ is the predicted probability observation for class c. + +It's harder to think about how I would do it for a Value function. There was the approach we saw before where the loss function was like so, +$$ +loss_Q = max(Q(s, a) + l(s,a)) - Q(s, a_E) +$$ +Where $l(s, a)$ is a vector that is positive for all values except for what the demonstrator took which is action $a_E$. + +The main issue with this loss function for the Value is that it does not capture the actual output values of the functions, just how they are relative to each other. Perhaps adding another layer can help transform it to the values it needs to be. This will take some more thought. + + + diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/Jan29.md b/content/research/deepreinforcementlearning/WeeklyProgress/Jan29.md new file mode 100644 index 0000000..a203d4f --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress/Jan29.md @@ -0,0 +1,65 @@ +# Weekly Progress Jan 29 + +## 1. Training From Demonstrations + +Training from demonstrations is the act of using previous data to help speed up the learning process. + +I read two papers on the topic: + +[1] Gabriel V. de la Cruz Jr., Yunshu Du, Matthew E. Taylor. **Pre-training Neural Networks with Human Demonstrations for Deep Reinforcement Learning**. + +https://arxiv.org/abs/1709.04083 + +The authors showed how you can speed up the training of a DQN network, especially under problems involving computer vision, if you first train the convolution layers by using a supervised loss between the actions the network would choose and the actions from the demonstration data given a state. + +[2] Todd Hester, Matej Vecerik, Olivier Pietquin, Marc Lanctot, Tom Schaul, Bilal Piot, Dan Horgan, John Quan, Andrew Sendonaris, Gabriel Dulac-Arnold, Ian Osband, John Agapiou, Joel Z. Leibo, Audrunas Gruslys. **Deep Q-learning from Demonstrations.** + +https://arxiv.org/abs/1704.03732 + +The authors showed how from "expert" demonstrations we can speed up the training of a DQN by incorporating the supervised loss into the loss function. + +### Supervised Loss + +What is supervised loss in the context of DQNs? +$$ +Loss = max(Q(s, a)+l(s,a )) - Q(s, a_E) +$$ +Where $a_E$ is the expert action, and $l(s, a)$ is a vector of positive values with an entry of zero for the expert action. + +The intuition behind this is that for the loss to be zero, the network would've had to have chosen the same action as the expert. The $l(s, a)$ term exists to ensure that there are no ties. + +### What I decided to do + +The main environment I chose to test these algorithms is Acrobot. It is a control theory problem and it has several physics related numbers as input. (Not image based) + +I noticed when implementing [1] at least for the non-convolution case, there's no point in trying to train earlier layers. Perhaps I'll try again when I move onto the atari gameplays... + +I decided against following [2] exactly. It's not that I disagree with the approach, but I don't like the need for "expert" data. If you decide to proceed anyways with non-expert data, you need to remember that it is incorporated into the loss function. Which means that you fall risk into learning sub-optimal policies. + +In the end, what I decided to do was the following + +1. Train a neural network that maps states->actions from demonstration data +2. Use that network to play through several simulated runs of the environment, state the (state, action, reward, next_state, done) signals and insert it into the experience replay buffer and train from those (**Pretrain step**) +3. Once the pretrain step is completed, replace the network that maps from demonstration data with the one you've been training in the pre-training step and continue with the regular algorithm + + + +## 2. Noisy Networks + +Based on this paper... + +Meire Fortunato, Mohammad Gheshlaghi Azar, Bilal Piot, Jacob Menick, Ian Osband, Alex Graves, Vlad Mnih, Remi Munos, Demis Hassabis, Olivier Pietquin, Charles Blundell, Shane Legg. **Noisy Networks for Exploration.** + +This paper describes adding parametric noise to the weights and biases and how it aids in exploration. The parameters of the noise are learned with gradient descent along with the other network parameters. + + + +For the noise distribution I used the Gaussian Normal. One property that's handy to know about it is the following +$$ +N(\mu, \sigma) = \mu + \sigma*N(0, 1) +$$ +In our case, the $\mu$ would be the typical weights and biases, and the $\sigma$ is a new parameter representing how much variation or uncertainty needs to be added. + +The concept is that as the network grows more confident about it's predictions, the variation in the weights start to decrease. This way the exploration is systematic and not something randomly injected like the epsilon-greedy strategy. + +The paper describes replacing all your linear densely connected layers with this noisy linear approach. \ No newline at end of file diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/Mar26.md b/content/research/deepreinforcementlearning/WeeklyProgress/Mar26.md new file mode 100644 index 0000000..bc303eb --- /dev/null +++ b/content/research/deepreinforcementlearning/WeeklyProgress/Mar26.md @@ -0,0 +1,11 @@ +# Progress for Week of March 26 + +## Parallelized Evolutionary Strategies + +When the parallel ES class is declared, I start a pool of workers that then gets sent with a loss function and its inputs to compute whenever calculating gradients. + +## Started Exploring Count-Based Exploration + +I started looking through papers on Exploration and am interested in using the theoretical niceness of Count-based exploration in tabular settings and being able to see their affects in the non-tabular case. + +""[Unifying Count-Based Exploration and Intrinsic Motivation](https://arxiv.org/abs/1606.01868)" creates a model of a arbitrary density model that follows a couple nice properties we would expect of probabilities. Namely, $P(S) = N(S) / n$ and $P'(S) = (N(S) + 1) / (n + 1)$. Where $N(S)$ represents the number of times you've seen that state, $n$ represents the total number of states you've seen, and $P'(S)$ represents the $P(S)$ after you have seen $S$ another time. With this model, we are able to solve for $N(S)$ and derive what the authors call a *Psuedo-Count*. \ No newline at end of file diff --git a/content/research/deepreinforcementlearning/WeeklyProgress/breakout.gif b/content/research/deepreinforcementlearning/WeeklyProgress/breakout.gif new file mode 100644 index 0000000..383917f Binary files /dev/null and b/content/research/deepreinforcementlearning/WeeklyProgress/breakout.gif differ diff --git a/content/research/deepreinforcementlearning/abstractspring2019.md b/content/research/deepreinforcementlearning/abstractspring2019.md new file mode 100644 index 0000000..3a8d5f0 --- /dev/null +++ b/content/research/deepreinforcementlearning/abstractspring2019.md @@ -0,0 +1,15 @@ +--- +showthedate: false +--- + +**Name:** Brandon Rozek + +Department of Computer Science + +**Mentor:** Dr. Ron Zacharski + +QEP: The Q-Value Policy Evaluation Algorithm + + + +*Abstract.* In Reinforcement Learning, sample complexity is often one of many concerns when designing algorithms. This concern outlines the number of interactions with a given environment that an agent needs in order to effectively learn a task. The Reinforcement Learning framework consists of finding a function (the policy) that maps states/scenarios to actions while maximizing the amount of reward from the environment. For example in video games, the reward is often characterized by some score. In recent years a variety of algorithms came out falling under the categories of Value-based methods and Policy-based methods. Value-based methods create a policy by approximating how much reward an agent is expected to receive if it performs the best actions from a given state. It is then common to choose the actions that maximizes such values. Meanwhile, in Policy-based methods, the policy function produces probabilities that an agent performs each action given a state and this is then optimized for the maximum reward. As such, Value-based methods produce deterministic policies while policy-based methods produce stochastic/probabilistic policies. Empirically, Value-based methods have lower sample complexity than Policy-based methods. However, in decision making not every situation has a best action associated with it. This is mainly due to the fact that real world environments are dynamic in nature and have confounding variables affecting the result. The QEP Algorithm combines both the Policy-based methods and Value-based methods by changing the policy's optimization scheme to involve approximate value functions. We have shown that this combines the benefits of both methods so that the sample complexity is kept low while maintaining a stochastic policy. \ No newline at end of file diff --git a/content/research/dimensionalityreduction.md b/content/research/dimensionalityreduction.md new file mode 100644 index 0000000..e8b9229 --- /dev/null +++ b/content/research/dimensionalityreduction.md @@ -0,0 +1,17 @@ +--- +Title: Dimensionality Reduction +Description: Reducing High Dimensional Datasets to what we can digest. +showthedate: false +--- + +# Dimensionality Reduction + +In the Summer of 2018, I was going to embark with another study on the topics pertaining to Dimensionality Reduction. Sadly the other student became busy a few weeks into the study. I decided to upload what we got through anyways for completeness. + +[Syllabus](syllabus) + +[Intro](intro) + +[Feature Selection](featureselection) + +[Optimality Criteria](optimalitycriteria) \ No newline at end of file diff --git a/content/research/dimensionalityreduction/featureselection.md b/content/research/dimensionalityreduction/featureselection.md new file mode 100644 index 0000000..02df890 --- /dev/null +++ b/content/research/dimensionalityreduction/featureselection.md @@ -0,0 +1,34 @@ +# Feature Selection + +Feature selection is the process of selecting a subset of relevant features for use in model construction. The core idea is that data can contain many features that are redundant or irrelevant. Therefore, removing it will not result in much loss of information. We also wish to remove features that do not help in our goal. + +Feature selection techniques are usually applied in domains where there are many features and comparatively few samples. + +## Techniques + +The brute force feature selection method exists to exhaustively evaluate all possible combinations of the input features, and find the best subset. The computational cost of this approach is prohibitively high and includes a considerable risk of overfitting to the data. + +The techniques below describe greedy approaches to this problem. Greedy algorithms are ones that don't search the entire possible space but instead converges towards local maximums/minimums. + +### Wrapper Methods + +This uses a predictive model to score feature subsets. Each new subset is used to train a model, which is tested on a hold-out set. The error rate of the model results in a score for that subset. This method is computationally intensive, but usually provides the best performing feature set for that particular type of model. + +### Filter Methods + +This method uses a proxy measure instead of the error rate. The proxy measure can be specifically chosen to be faster to compute while still capturing the essence of the feature set. Common implementations include: + +- Mutual information +- Pointwise mutual information +- Pearson product-moment correlation coefficient +- Relief-based algorithms +- Inter/intra class distances +- Scores of significance tests + +Many filters provide a feature ranking rather than producing an explicit best feature subset + +### Embedded Methods + +This is a catch-all group of techniques which perform feature selection as part of the model. For example, the LASSO linear model penalizes the regression coefficients shrinking unimportant ones to zero. + +Stepwise regression is a commonly used feature selection technique that acts greedily by adding the feature that results in the best result each turn. \ No newline at end of file diff --git a/content/research/dimensionalityreduction/intro.md b/content/research/dimensionalityreduction/intro.md new file mode 100644 index 0000000..b26faf3 --- /dev/null +++ b/content/research/dimensionalityreduction/intro.md @@ -0,0 +1,30 @@ +# Introduction to Dimensionality Reduction + +## Motivations + +We all have problems to solve, but the data we might have at our disposal is too sparse or has too many features that it makes it computationally difficult or maybe even impossible to solve the problem. + +### Types of Problems + +**Prediction**: This is taking some input and trying to predict an output of it. An example includes having a bunch of labeled pictures of people and having the computer predict who is in the next picture taken. (Face or Object Recognition) + +**Structure Discovery**: Find an alternative representation of the data. Usually used to find groups or alternate visualizations + +**Density Estimation**: Finding the best model that describes the data. An example includes explaining the price of a home depending on several factors. + +## Advantages + +- Reduces the storage space of data (possibly removing noise in the process!) +- Decreases complexity making algorithms run faster +- Removes multi-collinearity which in turn likely improves the performance of a given machine learning model + - Multi-collinearity usually indicates that multiple variables are correlated with each other. Most models make use of independent features to simplify computations. Therefore, ensuring independent features is important. +- Data becomes easier to visualize as it can be projected into 2D/3D space +- Lessens the chance of models *overfitting* + - This typically happens when you have less observations compared to variables (also known as sparse data) + - Overfitting leads to a model being able to have high accuracy on the test set, but generalize poorly to reality. +- Curse of dimensionality does not apply in resulting dataset + - Curse of dimensionality is that in high dimensional spaces, all points become equidistant + +## Disadvantages + +Data is lost through this method, potentially resulting in possibly insightful information being removed. Features from dimensionality reduction are typically harder to interpret leading to more confusing models. \ No newline at end of file diff --git a/content/research/dimensionalityreduction/optimalitycriteria.md b/content/research/dimensionalityreduction/optimalitycriteria.md new file mode 100644 index 0000000..035d250 --- /dev/null +++ b/content/research/dimensionalityreduction/optimalitycriteria.md @@ -0,0 +1,99 @@ +# Optimality Criteria + +Falling under wrapper methods, optimality criterion are often used to aid in model selection. These criteria provide a measure of fit for the data to a given hypothesis. + +## Akaike Information Criterion (AIC) + +AIC is an estimator of relative quality of statistical models for a given set of data. Given a collection of models for the data, AIC estimates the quality of each model relative to each other. + +This way, AIC provides a means for model selection. AIC offers an estimate of the relative information lost when a given model is used. + +This metric does not say anything about the absolute quality of a model but only serves for comparison between models. Therefore, if all the candidate models fit poorly to the data, AIC will not provide any warnings. + +It is desired to pick the model with the lowest AIC. + +AIC is formally defined as +$$ +AIC = 2k - 2\ln{(\hat{L})} +$$ + + +## Bayesian Information Criterion (BIC) + +This metric is based on the likelihood function and is closely related to the Akaike information criterion. It is desired to pick the model with the lowest BIC. + +BIC is formally defined as +$$ +BIC = \ln{(n)}k - 2\ln{(\hat{L})} +$$ + +Where $\hat{L}$ is the maximized value of the likelihood function for the model $M$. +$$ +\hat{L} = p(x | \hat{\theta}, M) +$$ +$x$ is the observed data, $n$ is the number of observations, and $k$ is the number of parameters estimated. + + + +### Properties of BIC + +- It is independent from the prior +- It penalizes the complexity of the model in terms of the number of parameters + +### Limitations of BIC + +- Approximations are only valid for sample sizes much greater than the number of parameters (dense data) +- Cannot handle collections of models in high dimension + +### Differences from AIC + +AIC is mostly used when comparing models. BIC asks the question of whether or not the model resembles reality. Even though they have similar functions, they are separate goals. + +## Mallow's $C_p$ + +$C_p$ is used to assess the fit of a regression model that has been estimated using ordinary least squares. A small value of $C_p$ indicates that the model is relatively precise. + +The $C_p$ of a model is defined as +$$ +C_p = \frac{\sum_{i =1}^N{(Y_i - Y_{pi})^2}}{S^2}- N + 2P +$$ + +- $Y_pi$ is the predicted value of the $i$th observation of $Y$ from the $P$ regressors + +- $S^2$ is the residual mean square after regression on the complete set of regressors and can be estimated by mean square error $MSE$, + +- $N$ is the sample size. + +An alternative definition is + + +$$ +C_p = \frac{1}{n}(RSS + 2d\hat{\sigma}^2) +$$ + +- $RSS$ is the residual sum of squares +- $d$ is the number of predictors +- $\hat{\sigma}^2$ refers to an estimate of the variances associated with each response in the linear model + +## Deviance Information Criterion + +The DIC is a hierarchical modeling generalization of the AIC and BIC. it is useful in Bayesian model selection problems where posterior distributions of the model was obtained by a Markov Chain Monte Carlo simulation. + +This method is only valid if the posterior distribution is approximately multivariate normal. + +Let us define the deviance as +$$ +D(\theta) = -2\log{(p(y|\theta))} + C +$$ +Where $y$ is the data and $\theta$ are the unknown parameters of the model. + +Let us define a helper variable $p_D$ as the following +$$ +p_D = \frac{1}{2}\hat{Var}(D(\theta)) +$$ +Finally the deviance information criterion can be calculated as +$$ +DIC = D(\bar{\theta}) + 2p_D +$$ +Where $\bar{theta}$ is the expectation of $\theta$. + diff --git a/content/research/dimensionalityreduction/syllabus.md b/content/research/dimensionalityreduction/syllabus.md new file mode 100644 index 0000000..fbdd26d --- /dev/null +++ b/content/research/dimensionalityreduction/syllabus.md @@ -0,0 +1,71 @@ +# Dimensionality Reduction Study + +Dimensionality reduction is the process of reducing the number of random variables under consideration. This study will last for 10 weeks, meeting twice a week for about an hour. + +## Introduction to Dimensionality Reduction (0.5 Week) + +- Motivations for dimensionality reduction +- Advantages of dimensionality reduction +- Disadvantages of dimensionality reduction + +## Feature Selection (3 Weeks) + +This is the process of selecting a subset of relevant features. The central premise of this technique is that many features are either redundant or irrelevant and thus can be removed without incurring much loss of information. + +### Metaheuristic Methods (1.5 Weeks) + +- Filter Method +- Wrapper Method +- Embedded Method + +### Optimality Criteria (0.5 Weeks) + +- Bayesian Information Criterion +- Mallow's C +- Akaike Information Criterion + +### Other Feature Selection Techniques (1 Week) + +- Subset Selection +- Minimum-Redundancy-Maximum-Relevance (mRMR) feature selection +- Global Optimization Formulations +- Correlation Feature Selection + +### Applications of Metaheuristic Techniques (0.5 Weeks) + +- Stepwise Regression +- Branch and Bound + +## Feature Extraction (6 Weeks) + +Feature extraction transforms the data in high-dimensional space to a space of fewer dimensions. In other words, feature extraction involves reducing the amount of resources required to describe a large set of data. + +### Linear Dimensionality Reduction (3 Weeks) + +- Principal Component Analysis (PCA) +- Singular Value Decomposition (SVD) +- Non-Negative Matrix Factorization +- Linear Discriminant Analysis (LDA) +- Multidimensional Scaling (MDS) +- Canonical Correlation Analysis (CCA) [If Time Permits] +- Linear Independent Component Analysis [If Time Permits] +- Factor Analysis [If Time Permits] + +### Non-Linear Dimensionality Reduction (3 Weeks) + +One approach to the simplification is to assume that the data of interest lie on an embedded non-linear manifold within higher-dimensional space. + +- Kernel Principal Component Analysis +- Nonlinear Principal Component Analysis +- Generalized Discriminant Analysis (GDA) +- T-Distributed Stochastic Neighbor Embedding (T-SNE) +- Self-Organizing Map +- Multifactor Dimensionality Reduction (MDR) +- Isomap +- Locally-Linear Embedding +- Nonlinear Independent Component Analysis +- Sammon's Mapping [If Time Permits] +- Hessian Eigenmaps [If Time Permits] +- Diffusion Maps [If Time Permits] +- RankVisu [If Time Permits] + diff --git a/content/research/lunac.md b/content/research/lunac.md new file mode 100644 index 0000000..39af59e --- /dev/null +++ b/content/research/lunac.md @@ -0,0 +1,17 @@ +--- +Title: LUNA-C Cluster +Description: Building a Beowulf Cluster for the University +showthedate: false +--- + +# LUNA-C + +LUNA-C stands for Large Universal Network Array of Computers and it was a project started back in August 2017 to introduce a cluster computing system to the University. I started this project in response to a want for more computing power to help with the Physics research I was doing at the time. + +I started this project and wrote a grant proposal and have brought on many students to help make this dream come true. The resources below give a look into all the thoughts and ideas that went along with the project. + +[May 2018 Poster](poster.pdf) + +[August 2018 Report](report.pdf) + +[June 2019 Presentation](/files/slides/buildinglinuxcluster.pdf) \ No newline at end of file diff --git a/content/research/lunac/LUNA-C Cluster Report.pdf b/content/research/lunac/LUNA-C Cluster Report.pdf new file mode 100644 index 0000000..12ac30c Binary files /dev/null and b/content/research/lunac/LUNA-C Cluster Report.pdf differ diff --git a/content/research/lunac/LUNACposter.pdf b/content/research/lunac/LUNACposter.pdf new file mode 100644 index 0000000..675ff16 Binary files /dev/null and b/content/research/lunac/LUNACposter.pdf differ diff --git a/content/research/physics.md b/content/research/physics.md new file mode 100644 index 0000000..6c6765f --- /dev/null +++ b/content/research/physics.md @@ -0,0 +1,13 @@ +--- +Title: Physics +Description: Help with Physics Research Projects +showthedate: false +--- + +## Physics Research + +For the two projects below, I worked on Quantum Research in a physics lab with a fellow student Hannah Killian and an advisor Dr. Hai Nguyen. I mostly assisted with the software support for the project and assisted in the mathematics in whatever way I can. + +[Modeling Population Dynamics of Incoherent and Coherent Excitation](/files/research/modellingpopulationdynamics.pdf) + +[Coherent Control of Atomic Population Using the Genetic Algorithm](/files/research/coherentcontrolofatomicpopulation.pdf) \ No newline at end of file diff --git a/content/research/progcomp.md b/content/research/progcomp.md new file mode 100644 index 0000000..6c6ec10 --- /dev/null +++ b/content/research/progcomp.md @@ -0,0 +1,14 @@ +--- +Title: Programming Competition +Description: Competition on Algorithms and Data Structures +showthedate: false +--- + +# Programming Competition +Back in the Fall of 2018, Harrison Crosse, Clare Arrington, and I all formed a team to compete in a programming competition. + +I didn't make many notes for this, but below are the ones I did make for this. + +[Strings](strings) + +[Number Theory](numbertheory) \ No newline at end of file diff --git a/content/research/progcomp/numbertheory.md b/content/research/progcomp/numbertheory.md new file mode 100644 index 0000000..78ad9b1 --- /dev/null +++ b/content/research/progcomp/numbertheory.md @@ -0,0 +1,295 @@ +# Number Theory + +## Prime Numbers + +A *prime number* is an integer $p > 1$ which is only divisible by $1$ and itself. + +If $p$ is a prime number, then $p = ab$ for integers $a \le b$ implies that $a = 1$ and $b = p$. + +### Definitions + +**Fundamental Theorem of Arithmetic**: Every integer can be expressed in only one way as a product of primes. + +**Prime factorization of $n$**: The unique set of numbers multiplying to $n$. + +**Factor**: A prime number $p$ is a *factor* of $x$ if it appears in its prime factorization. + +**Composite**: A number which is not prime + +### Finding Primes + +The easiest way to test if a given number $x$ is repeated division + +- After testing two, we only need to check odd numbers afterwards +- We only need to check until $\sqrt{x}$ since two numbers are perhaps multiplied to achieve $x$. + +#### Considerations if you don't have nice things + +The terminating condition of $i > \sqrt{x}$ is somewhat problematic, because `sqrt()` is a numerical function with imperfect precision. + +To get around this, you can change the termination condition to $i^2 > x$. Though then we get into the problem of potential overflow when working on large integers. + +The best solution if you have to deal with these issues is to compute $(i + 1)^2$ based on the result from $i^2$. +$$ +\begin{align*} +(i + 1)^2 &= i^2 + 2i + 1 +\end{align*} +$$ +So just add $(2i + 1)$ to the previous result. + +## Divisibility + +A lot of number theory concerns itself with the study of integer divisibility. + +### Definition + +**Divides:** We say that $b$ *divides* $a$ (denoted $b|a$) if $a = bk$ for some integer $k$. + +**Divisor:** If the above is true, then we say that $b$ is a *divisor* of $a$ + +**Multiple:** Given the above, we say that $a$ is a multiple of $b$. + +As a consequence of this definition, the smallest natural divisor of every non-zero integer is $1$. This is also known as the *least common divisor*. + +**Greatest Common Divisor $(gcd)$:** the *largest* divisor shared by a given pair of integers. + +**Relatively Prime**: Two integers are *relatively prime* if their greatest common divisor is $1$. + +**Reduced Form:** A fraction is said to be in *reduced form* if the greatest common divisor between the numerator and denominator is $1$. + +### Properties + +The greatest common divisor an integer has with itself is itself. +$$ +gcd(b, b) = b \tag{1.1} +$$ +The ordering of arguments to $gcd$ doesn't matter. Traditionally the larger value is placed in the first argument. +$$ +gcd(a, b) = gcd(b, a) \tag{1.2} +$$ +The greatest common divisor if $b$ divides $a$ between $a$ and $b$ is $b$. +$$ +b | a \implies gcd(a, b) = b \tag{1.3} +$$ + +This in part is because of two observations + +- $b$ is the greatest common divisor of $b$ from $(1.1)$ +- $b$ divides $a$, therefore it's a common divisor + +The greatest common divisor between $a$ and $b$ where $a = bt + r$ is the same as the greatest common divisor between $b$ and $r$. +$$ +a = bt + r \implies gcd(a, b) = gcd(b, r) \tag{1.4} +$$ +Let's work this out: $gcd(a, b) = gcd(bt + r, b)$. Since $bt$ is a multiple of $b$, we can add and subtract as many $bt$'s as we want without influencing the answer. This leads to $gcd(bt + r, b) = gcd(r, b) = gcd(b, r)$. + +### Euclid's Algorithm + +Using $(1.4)$ we can rewrite greatest common divisor problems in terms of the property in order to simplify the expression. Take a look at the example below: +$$ +\begin{align*} +gcd(34398, 2131) &= gcd(34398 \text{ mod } 2132, 2132) = gcd(2132, 286) \\ +gcd(2132, 286) &= gcd(2132 \text{ mod } 286, 286,) = gcd(286, 130) \\ +gcd(286, 130) &= gcd(286 \text{ mod } 130, 130) = gcd(130, 26) \\ +gcd(130, 26) &= gcd(130 \text{ mod } 26, 26,) = gcd(26, 0) +\end{align*} +$$ +Therefore, $gcd(34398, 2132) = 26$. + +### Least Common Multiple + +#### Definition + +The *least common multiple* $(lcm)$ is the smallest integer which is divided by both of a given pair of integers. Ex: $lcm(24, 36) = 72$. + +#### Properties + +The least common multiple of $x$ and $y$ is greater (or equal) than both $x$ and $y$. +$$ +lcm(x, y) \ge max(x,y) \tag{2.1} +$$ +The least common multiple of $x$ and $y$ is less than or equal to $x$ and $y$ multiplied together. +$$ +lcm(x, y) \le xy \tag{2.2} +$$ +Coupled with Euclid's algorithm we can derive the property that the least common multiple is equal to the pair of multiplied integers divided by their greatest common divisor. +$$ +lcm(x, y) = xy / gcd(x, y) \tag{2.3} +$$ + +#### Potential Problems + +Least common multiple arises when we want to compute the simultaneous periodicity of two distinct periodic events. When is the next year (after 2000) that the presidential election will coincide with the census? + +These events coincide every twenty years, because $lcm(4, 10) = 20$. + +## Modular Arithmetic + +We are not always interested in full answers, however. Sometimes the remainder suffices for our purposes. + +Example: Suppose your birthday this year falls on a Wednesday. What day of the week will it fall on next year? + +The remainder of the number of days between now and then (365 or 366) mod the number of days in a week. $365$ mod $7 = 1$. Which means that your birthday will fall on a Thursday. + +### Operations of Modular Arithmetic + +**Addition**: $(x + y)$ mod $n$ $=$ $((x $ mod $n) + (y$ mod $n))$ mod $n$ + +Example: How much small change will I have if given \$123.45 by my mother and \$94.67 by my father? +$$ +\begin{align*} +(12345 \text{ mod } 100) + (9467 \text{ mod } 100) &= (45 + 67) \text{ mod } 100 \\ +&= 12 \text{ mod } 100 +\end{align*} +$$ +**Subtraction** (Essentially addition with negatives): + +Example: Based on the previous example, how much small change will I have after spending \$52.53? +$$ +(12 \text{ mod } 100) - (53 \text{ mod } 100) = -41 \text{ mod } 100 = 59 \text{ mod } 100 +$$ +Notice the flip in signs, this can be generalized into the following form: +$$ +x \text{ mod } y = (y - x) \text{ mod } y +$$ +**Multiplication** (Otherwise known as repeated addition): +$$ +xy \text{ mod } n = (x \text{ mod } n)(y \text{ mod } n) \text{ mod n} +$$ +Example: How much change will you have if you earn \$17.28 per hour for 2,143 hours? +$$ +\begin{align*} +(1728 * 2143) \text{ mod } 100 &= (28 \text{ mod } 100)(43 \text{ mod 100}) \\ +&= 4 \text{ mod } 100 +\end{align*} +$$ +**Exponentiation** (Otherwise known as repeated multiplication): +$$ +x^y \text{ mod } n =(x \text{ mod n})^y \text{ mod } n +$$ +Example: What is the last digit of $2^{100}$? +$$ +\begin{align*} +2^3 \text{ mod } 10 &= 8 \\ +2^6 \text{ mod } 10 &= 8(8) \text{ mod } 10 \rightarrow 4 \\ +2^{12} \text{ mod } 10 &= 4(4) \text{ mod } 10 \rightarrow 6 \\ +2^{24} \text{ mod } 10 &= 6(6) \text{ mod } 10 \rightarrow 6 \\ +2^{48} \text{ mod } 10 &= 6(6) \text{ mod } 10 \rightarrow 6 \\ +2^{96} \text{ mod } 10 &= 6(6) \text{ mod } 10 \rightarrow 6\\ +2^{100} \text{ mod } 10 &= 2^{96}(2^3)(2^1) \text{ mod } 10 \\ + &= 6(8)(2) \text{ mod } 10 \rightarrow 6 +\end{align*} +$$ + +## Linear Congruences + +**Definition:** $ a \equiv b \text{ (mod m)} \iff m |(a-b)$ + +### Properties + +If $a$ mod $m$ is $b$, then $a$ is linearly congruent to $b$ in mod $m$. +$$ +a \text{ mod } m = b \implies a \equiv b \text{ (mod m)} \tag{3.1} +$$ +Let us show that from what we know so far... +$$ +\begin{align*} +a \text{ mod m} = b &\implies a = mk+b \hspace{.2in} \text{(for some $k \in \mathbb{Z}$)} \\ +&\implies a - b = mk + b - b \\ +&\iff a-b = m k \\ +&\iff m | (a - b) \\ +&\iff a \equiv b \hspace{.2in} \text{ (mod m)} +\end{align*} +$$ +**Example:** What set of integers satisfy the following congruence? +$$ +x \equiv 3 \text{ mod } 9 +$$ +**Scratch work:** +$$ +\begin{align*} +x \equiv 3 \text{ mod } 9 &\iff 9 | (x - 3) \\ +&\iff x - 3 = 9k \hspace{.2in} \text{ (for some $k \in \mathbb{Z}$)} \\ +&\iff x = 9k - 3 +\end{align*} +$$ + +### Operations on congruences + +#### Addition/Subtraction + +$$ +a \equiv b \text{ (mod n) and } c \equiv d \text{ (mod n) } \implies a + c \equiv b + d \text{ (mod n)} \tag{3.2} +$$ + +*Proof.* +$$ +\begin{align*} +a \equiv b \text{ (mod n) } &\implies n | (a - b) \\ +&\implies a - b = nk_1 \hspace{.2in} \text{ (for some $k_1 \in \mathbb{Z}$)} \\ +&\implies a = nk_1 + b\\ +c \equiv d \text{ (mod n) } &\implies n | (c - d) \\ +&\implies c - d = nk_2 \hspace{.2in} \text{ (for some $k_2 \in \mathbb{Z}$)} \\ +&\implies c = nk_2 + d \\ +a + c &= nk_1 + b + nk_2 + d \\ +&= n(k_1 + k_2) + (b + d) \\ +&=nk + (b + d) \hspace{.2in} \text{(for some $k \in \mathbb{Z}$)} \\ +&\implies (a + c) \text{ mod } n = b + d \\ +&\implies a+c \equiv b + d \text{ (mod n)} +\end{align*} +$$ + +#### Multiplication + +$$ +a \equiv b \text{ (mod n) } \implies ad \equiv bd \text{ (mod n)} \tag{3.3} +$$ + +*Proof.* +$$ +\begin{align*} +a \equiv b \text{ (mod n) } &\implies n | (a - b) \\ +&\implies a - b = nk_1 \hspace{.2in} \text{ (for some $k_1 \in \mathbb{Z}$)} \\ +&\implies d(a - b) = d(nk_1) \\ +&\implies da-db = n(dk_1) \\ +&\implies n | (da-db) \\ +&\implies da \equiv db \text{ (mod n)} +\end{align*} +$$ +Next Theorem +$$ +a \equiv b \text{ (mod n) and } c \equiv d \text{ (mod n) } \implies ac \equiv bd \text{ (mod n) } +$$ +*Proof.* +$$ +\begin{align*} +a \equiv b \text{ (mod n) } &\implies a = nk_1 + b \hspace{.2in} \text{ (for some $k_1 \in \mathbb{Z}$)} \\ +c \equiv d \text{ (mod n)} &\implies c = nk_2 + d \hspace{.2in} \text{ (for some $k_2 \in \mathbb{Z}$)} \\ +a * c &= (nk_1 + b)(nk_2+d) \\ + &=n^2k_1k_2 + bnk_2+dnk_1 +bd \\ + &= n(nk_1k_2+bk_2+dk_2) + bd \\ + &\implies ac \text{ mod } n = bd \\ + ac &\equiv bd \text{ (mod n)} +\end{align*} +$$ + +#### Division + +Let us define division as so +$$ +bb^{-1} \equiv 1 \text{ (mod n)} \\ +$$ +Theorem. +$$ +ad \equiv bd \text{ (mod dn) } \iff a \equiv b \text{ (mod n) } +$$ +*Proof.* +$$ +\begin{align*} +ad \equiv bd \text{ (mod dn) } &\implies ad - bd = dnk \\ +&\implies d(a-b) = d(nk) \\ +&\implies a-b = nk \\ +&\implies n | (a-b) \\ +&\implies a \equiv b \text{ (mod n)} +\end{align*} +$$ diff --git a/content/research/progcomp/strings.md b/content/research/progcomp/strings.md new file mode 100644 index 0000000..4051955 --- /dev/null +++ b/content/research/progcomp/strings.md @@ -0,0 +1,15 @@ +# Strings + +## Character Codes + +Character codes are mappings between numbers and symbols which make up a particular alphabet. + +The *American Standard Code for Information Interchange* (ASCII) is a single-byte character code where $2^7 = 128$ characters are specified. + +Symbol assignments were not done at random. Several interesting properties of the design make programming tasks easier: + +- All non-printable characters have either the first three bits as zero or all seven lowest bits as one. This makes it easy to eliminate them before displaying junk. +- Both the upper and lower case letters and the numerical digits appear sequentially +- We can get the numeric order of a letter by subtracting the first letter +- We can convert a character from uppercase to lowercase by $Letter - "A" + "a"$ + diff --git a/content/research/proglang.md b/content/research/proglang.md new file mode 100644 index 0000000..75a50e4 --- /dev/null +++ b/content/research/proglang.md @@ -0,0 +1,12 @@ +--- +Title: Programming Languages +Description: Designing and Implementing Programming Languages +showthedate: false +--- + +# Programming Languages +Back in the Fall of 2018, under the guidance of Ian Finlayson, I worked towards creating a programming language similar to SLOTH (Simple Language of Tiny Heft). The language as of now is interpreted and supports array based programming. + +[Github repository](https://github.com/brandon-rozek/sloth) outlining my work. + +[Short Notes](types) on Types of Programming Languages \ No newline at end of file diff --git a/content/research/proglang/types.md b/content/research/proglang/types.md new file mode 100644 index 0000000..5917223 --- /dev/null +++ b/content/research/proglang/types.md @@ -0,0 +1,243 @@ +# Types of Programming Languages + +Mostly content from Wikipedia + +https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Hardware_description_languages + +## Array Languages + +Array programming languages generalizes operations on scalars to apply transparently to vectors, matrices, and higher-dimensional arrays. + +Example Language: R + +In R everything is by default a vector, typing in + +```R +x <- 5 +``` + +Will create a vector of length 1 with the value 5. + +This is commonly used by the scientific and engineering community. Other languages include MATLAB, Octave, Julia, and the NumPy extension to Python. + +## Constraint Programming Languages + +A declarative programming language where relationships between variables are expressed as constraints. Execution proceeds by attempting to find values for the variables that satisfy all declared constraints. + +Example: Microsoft Z3 Theorem Prover + +```z3 +(declare-const a Int) +(declare-fun f (Int Bool) Int) +(assert (> a 10)) +(assert (< (f a true) 100)) +(check-sat) +``` + +## Command Line Interface Languages + +Commonly used to control jobs or processes + +```bash +#!/bin/bash +echo "hello, $USER. I wish to list some files of yours" +echo "listing files in the current directory, $PWD" +ls # list files +``` + +## Concurrent Languages + +Languages that support language constructs for concurrency. These may involve multi-threading, distributed computing, message passing, shared resources, and/or future and promises. + +Example: Erlang + +```erlang +ping(0, Pong_PID) -> + Pong_PID ! finished, + io:format("ping finished~n", []); + +ping(N, Pong_PID) -> + Pong_PID ! {ping, self()}, + receive + pong -> + io:format("Ping received pong~n", []) + end, + ping(N - 1, Pong_PID). + +pong() -> + receive + finished -> + io:format("Pong finished~n", []); + {ping, Ping_PID} -> + io:format("Pong received ping~n", []), + Ping_PID ! pong, + pong() + end. + +start() -> + Pong_PID = spawn(tut15, pong, []), + spawn(tut15, ping, [3, Pong_PID]). +``` + + + +## Data-oriented Languages + +These languages provide powerful ways of searching and manipulating relations. + +Example: SQL + +```sql +SELECT * FROM STATION +WHERE 50 < (SELECT AVG(TEMP_F); +``` + +Give all the information from stations whose average temperature is above 50 degrees F + +## Declarative Languages + +Declarative languages express the logic of a computation without describing its control flow in detail + +Example: SQL again + +The example code above doesn't tell the computer how to perform the query, just what you want. + +## Functional Languages + +Style of computer programs that treat computation as the evaluation of mathematical functions and avoid changing-state and having mutable data. + +```haskell +primes = filterPrime [2..] + where filterPrime (p:xs) = + p : filterPrime [x | x <- xs, x `mod` p /= 0] +``` + +## Imperative Languages + +The use of statements to change a program's state + +Example: C + +```c +#define FOOSIZE 10 +struct foo fooarr[FOOSIZE]; + +for(i = 0; i < FOOSIZE; i++) +{ + do_something(fooarr[i].data); +} +``` + + + +## Iterative Languages + +Languages built around or offering generators + +Example: Python + +```python +def countfrom(n): + while True: + yield n + n += 1 + +g = countfrom(0) +next(g) # 0 +next(g) # 1 +``` + +## List-based Languages -LISPs + +Family of programming languages with a history of fully parenthesized prefix notation. + +Example: Common Lisp + +```commonlisp + ;; Sorts the list using the > and < function as the relational operator. + (sort (list 5 2 6 3 1 4) #'>) ; Returns (6 5 4 3 2 1) + (sort (list 5 2 6 3 1 4) #'<) ; Returns (1 2 3 4 5 6) +``` + +## Logic Languages + +Programming paradigm based on formal logic. Expressions are written stating the facts and rules about some problem domain. + +Example: Prolog + +```prolog +mother_child(trude, sally). + +father_child(tom, sally). +father_child(tom, erica). +father_child(mike, tom). + +sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y). + +parent_child(X, Y) :- father_child(X, Y). +parent_child(X, Y) :- mother_child(X, Y). +``` + +```prolog +?- sibling(sally, erica). + Yes +``` + +## Symbolic Programming + +A programming paradigm in which the program can manipulate its own formulas and program components as if they were plain data. + +Example: Clojure + +Clojure is written in prefix notation, but with this macro, you can write in infix notation. + +```clojure +(defmacro infix + [infixed] + (list (second infixed) + (first infixed) + (last infixed))) +``` + + + +## Probabilistic Programming Language + +Adds the ability to describe probabilistic models and then perform inference in those models. + +Example: Stan + +```stan +model { + real mu; + + # priors: + L_u ~ lkj_corr_cholesky(2.0); + L_w ~ lkj_corr_cholesky(2.0); + to_vector(z_u) ~ normal(0,1); + to_vector(z_w) ~ normal(0,1); + + for (i in 1:N){ + mu = beta[1] + u[subj[i],1] + w[item[i],1] + + (beta[2] + u[subj[i],2] + w[item[i],2])*so[i]; + rt[i] ~ lognormal(mu,sigma_e); // likelihood + } +} +``` + + + +## Quick Summary of Programming Paradigms + +Imperative + +- Object Oriented +- Procedural + +Declarative + +- Functional +- Logic + +Symbolic Programming + diff --git a/content/research/publications.md b/content/research/publications.md new file mode 100644 index 0000000..35ea97b --- /dev/null +++ b/content/research/publications.md @@ -0,0 +1,22 @@ +--- +Title: Publications +Descriptions: Papers, Presentations, and Grants obtained +ShowDatesOnPosts: false +--- + +# Publications + +Brandon Rozek. "QEP: The Quality Policy Evaluation Algorithm", Research and Creativity Day at University of Mary Washington, 2019. + +Brandon Rozek, Stefano Coronado. "Beowulf Cluster for Research and Education", Research and Creativity Day at University of Mary Washington, 2018. + +Brandon Rozek. "Coherent Control of Atomic Population Using the Genetic Algorithm", Summer Science Institute Research Symposium, 2017. + +Hannah Killian, Brandon Rozek. "Modelling Population Dynamics of Incoherent and Coherent Excitation", Virginia Academy of Science, 2017. + +Hannah Killian, Brandon Rozek. “Modeling Population Dynamics of Incoherent and Coherent Excitation", Research and Creativity Day at University of Mary Washington, 2017. + + +# Grants + +Julia Arrington, Maia Magrakvilidze, Ethan Ramirez, Brandon Rozek "Beowulf Cluster for Research and Education", University of Mary Washington, 2017-2018 School Year diff --git a/content/research/reinforcementlearning.md b/content/research/reinforcementlearning.md new file mode 100644 index 0000000..2dff393 --- /dev/null +++ b/content/research/reinforcementlearning.md @@ -0,0 +1,45 @@ +--- +Title: Reinforcement Learning +Description: The study of optimally mapping situations to actions +--- + +# Reinforcement Learning +Reinforcement learning is the art of analyzing situations and mapping them to actions in order to maximize a numerical reward signal. + +In this independent study, I as well as Dr. Stephen Davies, will explore the Reinforcement Learning problem and its subproblems. We will go over the bandit problem, markov decision processes, and discover how best to translate a problem in order to **make decisions**. + +I have provided a list of topics that I wish to explore in a [syllabus](syllabus) + +## Readings + +In order to spend more time learning, I decided to follow a textbook this time. + +Reinforcement Learning: An Introduction + +By Richard S. Sutton and Andrew G. Barto + + +[Reading Schedule](readings) + + +## Notes + +The notes for this course, is going to be an extreemly summarized version of the textbook. There will also be notes on whatever side tangents Dr. Davies and I explore. + +[Notes page](notes) + +I wrote a small little quirky/funny report describing the bandit problem. Great for learning about the common considerations for Reinforcement Learning problems. + +[The Bandit Report](/files/research/TheBanditReport.pdf) + +## Code + +Code will occasionally be written to solidify the learning material and to act as aids for more exploration. + +[Github Link](https://github.com/brandon-rozek/ReinforcementLearning) + +Specifically, if you want to see agents I've created to solve some OpenAI environments, take a look at this specific folder in the Github Repository + +[Github Link](https://github.com/Brandon-Rozek/ReinforcementLearning/tree/master/agents) + + diff --git a/content/research/reinforcementlearning/notes.md b/content/research/reinforcementlearning/notes.md new file mode 100644 index 0000000..9b84aa1 --- /dev/null +++ b/content/research/reinforcementlearning/notes.md @@ -0,0 +1,12 @@ +# Lecture Notes for Reinforcement Learning + +[Chapter 1: An Introduction](intro) + +[Chapter 2: Multi-armed Bandits](bandits) + +[Chapter 3: Markov Decision Processes](mdp) + +[Chapter 4: Dynamic Programming](dynamic) + +[Chapter 5: Monte Carlo Methods](mcmethods) + diff --git a/content/research/reinforcementlearning/notes/bandits.md b/content/research/reinforcementlearning/notes/bandits.md new file mode 100644 index 0000000..2fabed1 --- /dev/null +++ b/content/research/reinforcementlearning/notes/bandits.md @@ -0,0 +1,144 @@ +# Chapter 2: Multi-armed Bandits + +Reinforcement learning *evaluates* the actions taken rather than accepting $instructions$ of the correct actions. This creates the need for active exploration. + +This chapter of the book goes over a simplified version of the reinforcement learning problem, that does not involve learning to act in more than one situation. This is called a *nonassociative* setting. + +In summation, the type of problem we are about to study is a nonassociative, evaluative feedback problem that is a simplified version of the $k$-armed bandit problem. + +## $K$-armed bandit problem + +Consider the following learning problem. You are faced repeatedly with a choice among $k$ different options/actions. After each choice you receive a numerical reward chosen from a stationary probability distribution that depends on the action you selected. + +Your objective (if you choose to accept it) is to maximize the expected total reward over some time period. Let's say $1000$ time steps. + +### Analogy + +This is called the $k$-armed bandit problem because it's an analogy of a slot machine. Slot machines are nick-named the "one-armed bandit", and the goal here is to play the slot machine that has the greatest value return. + +### Sub-goal + +We want to figure out which slot machine produces the greatest value. Therefore, we want to be able to estimate the value of a slot machine as close to the actual value as possible. + +### Exploration vs Exploitation + +If we maintain estimates of the action values, then at any time step there is at least one action whose estimated value is the greatest. We call these *greedy* actions. When you select one of these actions we say that you are *exploiting* your current knowledge of the values of the actions. + +If you instead select a non-greedy action, then you are *exploring*, because this enables you to better improve your estimate of the non-greedy action's value. + +Uncertainty is such that at least one of the other actions probably better than the greedy action, you just don't know which one yet. + +## Action-value Methods + +In this section, we will look at simple balancing methods in how to gain the greatest reward through exploration and exploitation. + +We begin by looking more closely at some simple methods for estimating the values of actions and for using said estimates to make action selection decisions. + +### Sample-average method + +One natural way to estimate this is by averaging the rewards actually received +$$ +Q_t(a) = \frac{\sum_{i = 1}^{t - 1}R_i * \mathbb{I}_{A_i = 1}}{\sum_{i = 1}^{t - 1}\mathbb{I}_{A_i = 1}} +$$ +where $\mathbb{I}_{predicate}$ denotes the random variable that is 1 if the predicate is true and 0 if it is not. If the denominator is zero (we have not experienced the reward), then we assume some default value such as zero. + +### Greedy action selection + +This is where you choose greedily all the time. +$$ +A_t = argmax_a(Q_t(a)) +$$ + +### $\epsilon$-greedy action selection + +This is where we choose greedily most of the time, except for a small probability $\epsilon$. Where instead of selecting greedily, we select randomly from among all the actions with equal probability. + +### Comparison of greedy and $\epsilon$-greedy methods + +The advantage of $\epsilon$-greedy over greedy methods depends on the task. With noisier rewards it takes more exploration to find the optimal action, and $\epsilon$-greedy methods should fare better relative to the greedy method. However, if the reward variances were zero, then the greedy method would know the true value of each action after trying it once. + +Suppose the bandit task were non-stationary, that is, the true values of actions changed over time. In this case exploration is needed to make sure one of the non-greedy actions has not changed to become better than the greedy one. + +### Incremental Implementation + +There is a way to update averages using small constant computations rather than storing the the numerators and denominators separate. + +Note the derivation for the update formula +$$ +\begin{align} +Q_{n + 1} &= \frac{1}{n}\sum_{i = 1}^n{R_i} \\ +&= \frac{1}{n}(R_n + \sum_{i = 1}^{n - 1}{R_i}) \\ +&= \frac{1}{n}(R_n + (n - 1)\frac{1}{n-1}\sum_{i = 1}^{n - 1}{R_i}) \\ +&= \frac{1}{n}{R_n + (n - 1)Q_n} \\ +&= \frac{1}{n}(R_n + nQ_n - Q_n) \\ +&= Q_n + \frac{1}{n}(R_n - Q_n) \tag{2.3} +\end{align} +$$ +With formula 2.3, the implementation requires memory of only $Q_n$ and $n$. + +This update rule is a form that occurs frequently throughout the book. The general form is +$$ +NewEstimate = OldEstimate + StepSize(Target - OldEstimate) +$$ + +### Tracking a Nonstationary Problem + +As noted earlier, we often encounter problems that are nonstationary, in such cases it makes sense to give more weight to recent rewards than to long-past rewards. One of the most popular ways to do this is to use a constant value for the $StepSize​$ parameter. We modify formula 2.3 to be +$$ +\begin{align} +Q_{n + 1} &= Q_n + \alpha(R_n - Q_n) \\ +&= \alpha R_n + Q_n - \alpha Q_n \\ +&= \alpha R_n + (1 - \alpha)Q_n \\ +&= \alpha R_n + (1 - \alpha)(\alpha R_{n - 1} + (1-\alpha)Q_{n - 1}) \\ +&= \alpha R_n + (1 - \alpha)(\alpha R_{n - 1} + (1-\alpha)(\alpha R_{n - 2} + (1 - a)Q_{n - 2})) \\ +&= \alpha R_n + (1-\alpha)\alpha R_{n - 1} + (1-\alpha)^2\alpha R_{n - 2} + \dots + (1-\alpha)^nQ_1 \\ +&= (1-\alpha)^nQ_1 + \sum_{i = 1}^n{\alpha(1-\alpha)^{n - i}R_i} +\end{align} +$$ +This is a weighted average since the summation of all the weights equal one. Note here that the farther away a value is from the current time, the more times $(1-\alpha)$ gets multiplied by itself. Hence making it less influential. This is sometimes called an *exponential recency-weighted average*. + +### Manipulating $\alpha_n(a)$ + +Sometimes it is convenient to vary the step-size parameter from step to step. We can denote $\alpha_n(a)$ to be a function that determines the step-size parameter after the $n$th selection of action $a$. As noted before $\alpha_n(a) = \frac{1}{n}$ results in the sample average method which is guaranteed to converge to the truth action values assuming a large number of trials. + +A well known result in stochastic approximation theory gives us the following conditions to assure convergence with probability 1: +$$ +\sum_{n = 1}^\infty{\alpha_n(a) = \infty} \and \sum_{n = 1}^{\infty}{\alpha_n^2(a) \lt \infty} +$$ +The first condition is required to guarantee that the steps are large enough to overcome any initial conditions or random fluctuations. The second condition guarantees that eventually the steps become small enough to assure convergence. + +**Note:** Both convergence conditions are met for the sample-average case but not for the constant step-size parameter. The latter condition is violated in the constant parameter case. This is desirable since if the rewards are changing then we don't want it to converge to any one parameter. + +### Optimistic Initial Values + +The methods discussed so far are biased by their initial estimates. Another downside is that these values are another set of parameters that must be chosen by the user. Though these initial values can be used as a simple way to encourage exploration. + +Let's say you set an initial estimate that is wildly optimistic. Whichever actions are initially selected, the reward is less than the starting estimates. Therefore, the learner switches to other actions, being *disappointed* with the rewards it was receiving. + +The result of this is that all actions are tried several times before their values converge. It even does this if the algorithm is set to choose greedily most of the time! + +![1536284892566](/home/rozek/Pictures/1536284892566.png) + +This simple trick is quite effective for stationary problems. Not so much for nonstationary problems since the drive for exploration only happens at the beginning. If the task changes, creating a renewed need for exploration, this method would not catch it. + +### Upper-Confidence-Bound Action Selection + +Exploration is needed because there is always uncertainty about the accuracy of the action-value estimates. The greedy actions are those that look best at the present but some other options may actually be better. Let's choose options that have potential for being optimal, taking into account how close their estimates are to being maximal and the uncertainties in those estimates. +$$ +A_t = argmax_a{(Q_t(a) + c\sqrt{\frac{ln(t)}{N_t(a)}})} +$$ +where $N_t(a)$ denotes the number of times that $a$ has been selected prior to time $t$ and $c > 0$ controls the degree of exploration. + +###Associative Search (Contextual Bandits) + +So far, we've only considered nonassociative tasks, where there is no need to associate different actions with different situations. However, in a general reinforcement learning task there is more than one situation and the goal is to learn a policy: a mapping from situations to the actions that are best in those situations. + +For sake of continuing our example, let us suppose that there are several different $k$-armed bandit tasks, and that on each step you confront one of these chosen at random. To you, this would appear as a single, nonstationry $k$-armed bandit task whose true action values change randomly from step to step. You could try using one of the previous methods, but unless the true action values change slowly, these methods will not work very well. + +Now suppose, that when a bandit task is selected for you, you are given some clue about its identity. Now you can learn a policy association each task, singled by the clue, with the best action to take when facing that task. + +This is an example of an *associative search* task, so called because it involves both trial-and-error learning to *search* for the best actions, and *association* of these actions with situations in which they are best. Nowadays they're called *contextual bandits* in literature. + +If actions are allowed to affect the next situation as well as the reward, then we have the full reinforcement learning problem. This will be presented in the next chapter of the book with its ramifications appearing throughout the rest of the book. + +![1536321791927](/home/rozek/Pictures/1536321791927.png) \ No newline at end of file diff --git a/content/research/reinforcementlearning/notes/dynamic.md b/content/research/reinforcementlearning/notes/dynamic.md new file mode 100644 index 0000000..708b258 --- /dev/null +++ b/content/research/reinforcementlearning/notes/dynamic.md @@ -0,0 +1,130 @@ +# Chapter 4: Dynamic Programming + +Dynamic programming refers to a collection of algorithms that can be used to compute optimal policies given a perfect model of the environment as a Markov decision process (MDP). + +Classic DP algorithms are of limited utility due to their assumption of a perfect model and their great computational expense. + +Let's assume that the environment is a finite MDP. We assume its state, action, and reward sets, $\mathcal{S}, \mathcal{A}, \mathcal{R}$ are finite, and that its dynamics are given by a set of probabilities $p(s^\prime, r | s , a)$. + +The key idea of dynamic programming, and of reinforcement learning is the use of value functions to organize and structure the search for good policies. In this chapter, we show how dynamic programming can be used to compute the value functions defined in Chapter 3. We can easily obtain optimal policies once we have found the optimal value functions which satisfy the Bellman optimality equations. + +## Policy Evaluation + +First we consider how to compute the state-value function for an arbitrary policy. The existence and uniqueness of a state-value function for an arbitrary policy are guaranteed as long as either the discount rate is less than one or eventual termination is guaranteed from all states under the given policy. + +Consider a sequence of approximate value functions. The initial approximation, $v_0$, is chosen arbitrarily (except that the terminal state must be given a value of zero) and each successive approximation is obtained by using the Bellman equation for $v_\pi$ as an update rule: +$$ +v_{k + 1} = \sum_{a}{\pi(a |s)\sum_{s^\prime, r}{p(s^\prime,r|s,a)[r + \gamma v_k(s^\prime)]}} +$$ +This algorithm is called *iterative policy evaluation*. + +To produce each successive approximation, $v_{k + 1}$ from $v_k$, iterative policy evaluation applies the same operation to each state $s$: it replaces the old value of $s$ with a new value obtained from the old values of the successor states of $s$, and the expected immediate rewards, along all the one-step transitions possible under the policy being evaluated. + +**Iterative Policy Evaluation** + +``` +Input π, the policy to be evaluated +Initialize an array V(s) = 0, for all s ∈ S+ +Repeat + ∆ ← 0 + For each s ∈ S: + v ← V(s) + V(s) ← ∑_a π(a|s) ∑_s′,r p(s′,r|s,a)[r+γV(s′)] + ∆ ← max(∆,|v−V(s)|) +until ∆ < θ (a small positive number) +Output V ≈ v_π +``` + +### Grid World Example + +Consider a grid world where the top left and bottom right squares are the terminal state. Now consider that every other square, produces a reward of -1, and the available actions on each state is {up, down, left, right} as long as that action keeps the agent on the grid. Suppose our agent follows the equiprobable random policy. + +![1540262811089](/home/rozek/Documents/Research/Reinforcement Learning/1540262811089.png) + +## Policy Improvement + +One reason for computing the value function for a policy is to help find better policies. Suppose we have determined the value function $v_\pi$ for an arbitrary deterministic policy $\pi$. For some state $s$ we would like to know whether or not we should change the policy to determinatically chose another action. We know how good it is to follow the current policy from $s$, that is $v_\pi(s)$, but would it be better or worse to change to the new policy? + +One way to answer this question is to consider selecting $a$ in $s$ and thereafter follow the existing policy, $\pi$. The key criterion is whether the this produces a value greater than or less than $v_\pi(s)$. If it is greater, then one would expect it to be better still to select $a$ every time $s$ is encountered, and that the new policy would in fact be a better one overall. + +That this is true is a special case of a general result called the *policy improvement theorem*. Let $\pi$ and $\pi^\prime$ be any pair of deterministic policies such that for all $s \in \mathcal{S}$. +$$ +q_\pi(s, \pi^\prime(s)) \ge v_\pi(s) +$$ +So far we have seen how, given a policy and its value function, we can easily evaluate a change in the policy at a single state to a particular action. It is a natural extension to consider changes at all states and to all possible actions, selecting at each state the action that appears best according to $q_\pi(s, a)$. In other words, to consider the new *greedy* policy, $\pi^\prime$, given by: +$$ +\pi^\prime = argmax (q_\pi(s, a)) +$$ +So far in this section we have considered the case of deterministic policies. We will not go through the details, but in fact all the ideas of this section extend easily to stochastic policies. + +## Policy Iteration + +Once a policy, $\pi$, has been improved using $v_\pi$ to yield a better policy, $\pi^\prime$, we can then compute $v_{\pi^\prime}$ and improve it again to yield an even better $\pi^{\prime\prime}$. We can thus obtain a sequence of monotonically improving policies and value functions. + +Each policy is guaranteed to be a strict improvement over the previous one (unless its already optimal). Since a finite MDP has only a finite number of policies, this process must converge to an optimal policy and optimal value function in a finite number of iterations. + +This way of finding an optimal policy is called *policy iteration*. + +Algorithm + +``` +1. Initialization + V(s) ∈ R and π(s) ∈ A(s) arbitrarily for all s ∈ S +2. Policy Evaluation + Repeat + ∆ ← 0 + For each s∈S: + v ← V(s) + V(s) ← ∑_{s′,r} p(s′,r|s,π(s))[r + γV(s′)] + ∆ ← max(∆,|v − V(s)|) + until ∆ < θ (a small positive number) +3. Policy Improvement + policy-stable ← true + For each s ∈ S: + old-action ← π(s) + π(s) ← arg max_a ∑_{s′,r} p(s′,r|s,a)[r + γV(s′)] + If old-action != π(s), then policy-stable ← false + If policy-stable, then stop and return V ≈ v_∗, + and π ≈ π_∗; else go to 2 +``` + +## Value Iteration + +One drawback to policy iteration is that each of its iterations involve policy evaluation, which may itself be a protracted iterative computation requiring multiple sweeps through the state set. If policy evaluation is done iteratively, then convergence exactly to $v_\pi$ occurs only in the limit. Must we wait for exact convergence, or can we stop short of that? + +In fact, the policy evaluation step of policy iteration can be truncated in several ways without losing the convergence guarantee of policy iteration. One important special case is when policy evaluation is stopped after one sweep. This algorithm is called value iteration. + +Another way of understanding value iteration is by reference to the Bellman optimality equation. Note that value iteration is obtained simply by turning the Bellman optimality equation into an update rule. Also note how value iteration is identical to the policy evaluation update except that it requires the maximum to be taken over all actions. + +Finally, let us consider how value iteration terminates. Like policy evaluation, value iteration formally requires an infinite number of iterations to converge exactly. In practice, we stop once the value function changes by only a small amount. + +``` +Initialize array V arbitrarily (e.g., V(s) = 0 for all +s ∈ S+) + +Repeat + ∆ ← 0 + For each s ∈ S: + v ← V(s) + V(s) ← max_a∑_{s′,r} p(s′,r|s,a)[r + γV(s′)] + ∆ ← max(∆, |v − V(s)|) +until ∆ < θ (a small positive number) + +Output a deterministic policy, π ≈ π_∗, such that + π(s) = arg max_a ∑_{s′,r} p(s′,r|s,a)[r + γV(s′)] +``` + +Value iteration effectively combines, in each of its sweeps, one sweep of policy evaluation and one sweep of policy improvement. Faster convergence is often achieved by interposing multiple policy evaluation sweeps between each policy improvement sweep. + +## Asynchronous Dynamic Programming + +*Asynchronous* DP algorithms are in-place DP algorithms that are not organized in terms of systematic sweeps of the state set. These algorithms update the values of states in any order whatsoever, using whatever value of other states happen to be available. + +To converge correctly, however, an asynchronous algorithm must continue to update the value of all the states: it can't ignore any state after some point in the computation. + +## Generalized Policy Iteration + +Policy iteration consists of two simultaneous, iterating processes, one making the value function consistent with the current policy (policy evaluation) and the other making the policy greedy with respect to the current value function (policy improvement). + +We use the term *generalized policy iteration* (GPI) to competing and cooperating. They compete in the sense that they pull in opposing directions. Making the policy greedy with respect to the value function typically makes the value function incorrect for the changed policy. Making the value function consistent with the policy typically causes the policy to be greedy. In the long run, however, the two processes interact to find a single joint solution. + diff --git a/content/research/reinforcementlearning/notes/intro.md b/content/research/reinforcementlearning/notes/intro.md new file mode 100644 index 0000000..5b378ba --- /dev/null +++ b/content/research/reinforcementlearning/notes/intro.md @@ -0,0 +1,66 @@ +# Introduction to Reinforcement Learning Day 1 + +Recall that this course is based on the book -- + +Reinforcement Learning: An Introduction by Richard S. Sutton and Andrew G. Barto + + + +These notes really serve as talking points for the overall concepts described in the chapter and are not meant to stand for themselves. Check out the book for more complete thoughts :) + + + +**Reinforcement Learning** is learning what to do -- how to map situations to actions -- so as to maximize a numerical reward signal. There are two characteristics, trial-and-error search and delayed reward, that are the two most important distinguishing features of reinforcement learning. + + + +Markov decision processes are intended to include just these three aspects: sensation, action, and goal(s). + + + +Reinforcement learning is **different** than the following categories + +- Supervised learning: This is learning from a training set of labeled examples provided by a knowledgeable external supervisor. In interactive problems it is often impractical to obtain examples of desired behavior that are both correct and representative of all situations in which the agent has to act. +- Unsupervised learning: Reinforcement learning is trying to maximize a reward signal as opposed to finding some sort of hidden structure within the data. + + + +One of the challenges that arise in reinforcement learning is the **trade-off** between exploration and exploitation. The dilemma is that neither exploration nor exploitation can be pursued exclusively without failing at the task. + + + +Another key feature of reinforcement learning is that it explicitly considers the whole problem of a goal-directed agent interacting with an uncertain environment. This is different than supervised learning since they're concerned with finding the best classifier/regression without explicitly specifying how such an ability would finally be useful. + + + +A complete, interactive, goal-seeking agent can also be a component of a larger behaving system. A simple example is an agent that monitors the charge level of a robot's battery and sends commands to the robot's control architecture. This agent's environment is the rest of the robot together with the robot's environment. + + + +## Definitions + +A policy defines the learning agent's way of behaving at a given time + + + +A reward signal defines the goal in a reinforcement learning problem. The agent's sole objective is to maximize the total reward it receives over the long run + + + +A value function specifies what is good in the long run. Roughly speaking, the value of a state is the total amount of reward an agent can expect to accumulate over the future, starting from that state. Without rewards there could be no value,s and the only purpose of estimating values is to achieve more reward. We seek actions that bring about states of highest value. + + + +Unfortunately, it is much harder to determine values than it is to determine rewards. The most important component of almost all reinforcement learning algorithms we consider is a method for efficiently estimating values. + + + +**Look at Tic-Tac-Toe example** + + + +Most of the time in a reinforcement learning algorithm, we move greedily, selecting the move that leads to the state with greatest value. Occasionally, however, we select randomly from amoung the other moves instead. These are called exploratory moves because they cause us to experience states that we might otherwise never see. + + + +Summary: Reinforcement learning is learning by an agent from direct interaction wit its environment, without relying on exemplary supervision or complete models of the environment. \ No newline at end of file diff --git a/content/research/reinforcementlearning/notes/mcmethods.md b/content/research/reinforcementlearning/notes/mcmethods.md new file mode 100644 index 0000000..51543e8 --- /dev/null +++ b/content/research/reinforcementlearning/notes/mcmethods.md @@ -0,0 +1,110 @@ +# Chapter 5: Monte Carlo Methods + +Monte Carlo methods do not assume complete knowledge of the environment. They require only *experience* which is a sample sequence of states, actions, and rewards from actual or simulated interaction with an environment. + +Monte Carlo methods are ways of solving the reinforcement learning problem based on averaging sample returns. To ensure that well-defined returns are available, we define Monte Carlo methods only for episodic tasks. Only on the completion of an episode are value estimates and policies changed. + +Monte Carlo methods sample and average returns for each state-action pair is much like the bandit methods explored earlier. The main difference is that there are now multiple states, each acting like a different bandit problems and the problems are interrelated. Due to all the action selections undergoing learning, the problem becomes nonstationary from the point of view of the earlier state. + +## Monte Carlo Prediction + +Recall that the value of a state is the expected return -- expected cumulative future discounted reward - starting from that state. One way to do it is to estimate it from experience by averaging the returns observed after visits to that state. + +Each occurrence of state $s$ in an episode is called a *visit* to $s$. The *first-visit MC method* estimates $v_\pi(s)$ as the average of the returns following first visits to $s$, whereas the *every-visit MC method* averages the returns following all visits to $s$. These two Monte Carlo methods are very similar but have slightly different theoretical properties. + +First-visit MC prediction + +``` +Initialize: + π ← policy to be evaluated + V ← an arbitrary state-value function + Returns(s) ← an empty list, for all s ∈ S + +Repeat forever: + Generate an episode using π + For each state s appearing in the episode: + G ← the return that follows the first occurrence of +s + Append G to Returns(s) + V(s) ← average(Returns(s)) +``` + +## Monte Carlo Estimation of Action Values + +If a model is not available then it is particularly useful to estimate *action* values rather than state values. With a model, state values alone are sufficient to define a policy. Without a model, however, state values alone are not sufficient. One must explicitly estimate the value of each action in order for the values to be useful in suggesting a policy. + +The only complication is that many state-action pairs may never be visited. If $\pi$ is a deterministic policy, then in following $\pi$ one will observe returns only for one of the actions from each state. With no returns to average, the Monte Carlo estimates of the other actions will not improve with experience. This is a serious problem because the purpose of learning action values is to help in choosing among the actions available in each state. + +This is the general problem of *maintaining exploration*. For policy evaluation to work for action values, we must assure continual exploration. One way to do this is by specifying that the episodes *start in a state-action pair*, and that each pair has a nonzero probability of being selected as the start. We call this the assumption of *exploring starts*. + +## Monte Carlo Control + +We made two unlikely assumptions above in order to easily obtain this guarantee of convergence for the Monte Carlo method. One was that the episodes have exploring starts, and the other was that policy evaluation could be done with an infinite number of episodes. + +Monte Carlo Exploring Starts + +``` +Initialize, for all s ∈ S, a ∈ A(s): + Q(s,a) ← arbitrary + π(s) ← arbitrary + Returns(s,a) ← empty list + +Repeat forever: + Choose S_0 ∈ S and A_0 ∈ A(S_0) s.t. all pairs have probability > 0 + Generate an episode starting from S_0,A_0, following +π + For each pair s,a appearing in the episode: + G ← the return that follows the first occurrence of +s,a + Append G to Returns(s,a) + Q(s,a) ← average(Returns(s,a)) + For each s in the episode: + π(s) ← arg max_a Q(s,a) +``` + +## Monte Carlo Control without Exploring Starts + +The only general way to ensure that actions are selected infinitely often is for the agent to continue to select them. There are two approaches ensuring this, resulting in what we call *on-policy* methods and *off-policy* methods. + +On-policy methods attempt to evaluate or improve the policy that is used to make decisions, whereas off-policy methods evaluate or improve a policy different from that used to generate the data. + +In on-policy control methods the policy is generally *soft*, meaning that $\pi(a|s)$ for all $a \in \mathcal{A}(s)$. The on-policy methods in this section uses $\epsilon$-greedy policies, meaning that most of the time they choose an action that has maximal estimated action value, but with probability $\epsilon$ they instead select an action at random. + +On-policy first-visit MC control (for $\epsilon$-soft policies) + +``` + +``` + +Initialize, for all $s \in \mathcal{S}$, $a \in \mathcal{A}(s)$: + + $Q(s, a)$ ← arbitrary + + $Returns(s,a)$ ← empty list + + $\pi(a|s)$ ← an arbitrary $\epsilon$-soft policy + +Repeat forever: + + (a) Generate an episode using $\pi$ + + (b) For each pair $s,a$ appearing in the episoe + +​ $G$ ← the return that follows the first occurance of s, a + +​ Append $G$ to $Returns(s,a)$ + +​ $Q(s, a)$ ← average($Returns(s,a)$) + + (c) For each $s$ in the episode: + +​ $A^*$ ← argmax$_a Q(s,a)$ (with ties broken arbitrarily) + +​ For all $a \in \mathcal{A}(s)$: + +​ $\pi(a|s)$ ← $\begin{cases} 1 - \epsilon + \epsilon / |\mathcal{A}(s)| & a = A^* \\ \epsilon / | \mathcal{A}(s)| & a \neq A^* \end{cases}$ + +``` + +``` + diff --git a/content/research/reinforcementlearning/notes/mdp.md b/content/research/reinforcementlearning/notes/mdp.md new file mode 100644 index 0000000..cde47b2 --- /dev/null +++ b/content/research/reinforcementlearning/notes/mdp.md @@ -0,0 +1,193 @@ +# Chapter 3: Finite Markov Decision Processes + +Markov Decision processes are a classical formalization of sequential decision making, where actions influence not just immediate rewards, but also subsequent situations, or states, and through those future rewards. Thus MDPs involve delayed reward and the need to trade-off immediate and delayed reward. Whereas in bandit problems we estimated the value of $q_*(a)$ of each action $a$, in MDPs we estimate the value of $q_*(s, a)$ of each action $a$ in state $s$. + +MDPs are a mathematically idealized form of the reinforcement learning problem. As we will see in artificial intelligence, there is often a tension between breadth of applicability and mathematical tractability. This chapter will introduce this tension and discuss some of the trade-offs and challenges that it implies. + +## Agent-Environment Interface + +The learner and decision maker is called the *agent*. The thing it interacts with is called the *environment*. These interact continually, the agent selecting actions and the environment responding to these actions and presenting new situations to the agent. + +The environment also give rise to rewards, special numerical values that the agent seeks to maximize over time through its choice of actions. + +![1536511147205](/home/rozek/Documents/Research/Reinforcement Learning/1536511147205.png) + +To make the future paragraphs clearer, a Markov Decision Process is a discrete time stochastic control process. It provides a mathematical framework for modeling decision making in situations where outcomes are partly random and partly under the control of the decision maker. + +In a *finite* MDP, the set of states, actions, and rewards all have a finite number of elements. In this case, the random variables R_t and S_t have a well defined discrete probability distribution dependent only on the preceding state and action. +$$ +p(s^\prime | s,a) = \sum_{r \in \mathcal{R}}{p(s^\prime, r|s, a)} +$$ +Breaking down the above formula, it's just an instantiation of the law of total probability. If you partition the probabilistic space by the reward, if you sum up each partition you should get the overall space. This formula has a special name: the *state-transition probability*. + +From this we can compute the expected rewards for each state-action pair by multiplying each reward with the probability of getting said reward and summing it all up. +$$ +r(s, a) = \sum_{r \in \mathcal{R}}{r}\sum_{s^\prime \in \mathcal{S}}{p(s^\prime, r|s,a)} +$$ +The expected reward for a state-action-next-state triple is +$$ +r(s, a, s^\prime) = \sum_{r \in \mathcal{R}}{r\frac{p(s^\prime, r|s,a)}{p(s^\prime|s,a)}} +$$ +I wasn't able to piece together this function in my head like the others. Currently I imagine it as if we took the formula before and turned the universe of discourse from the universal set to the state where $s^\prime$ occurred. + +The MDP framework is abstract and flexible and can be applied to many different problems in many different ways. For example, the time steps need not refer to fixed intervals of real time; they can refer to arbitrary successive states of decision making and acting. + +### Agent-Environment Boundary + +In particular, the boundary between agent and environment is typically not the same as the physical boundary of a robot's or animals' body. Usually, the boundary is drawn closer to the agent than that. For example, the motors and mechanical linkages of a robot and its sensing hardware should usually be considered parts of the environment rather than parts of the agent. + +The general rule we follow is that anything that cannot be changed arbitrarily by the agent is considered to be outside of it and thus part of its environment. We do not assume that everything in the environment is unknown to the agent. For example, the agent often knows quite a bit about how its rewards are computed as a function of its actions and the states in which they are taken. But we always consider the reward computation to be external to the agent because it defines the task facing the agent and thus must be beyond its ability to change arbitrarily. The agent-environment boundary represents the limit of the agent's absolute control, not of its knowledge. + +This framework breaks down whatever the agent is trying to achieve to three signals passing back and forth between an agent and its environment: one signal to represent the choices made by the agent, one signal to represent the basis on which the choices are made (the states), and one signal to define the agent's goal (the rewards). + +### Example 3.4: Recycling Robot MDP + +Recall that the agent makes a decision at times determined by external events. At each such time the robot decides whether it should + +(1) Actively search for a can + +(2) Remain stationary and wait for someone to bring it a can + +(3) Go back to home base to recharge its battery + +Suppose the environment works as follows: the best way to find cans is to actively search for them, but this runs down the robot's battery, whereas waiting does not. Whenever the robot is searching the possibility exists that its battery will become depleted. In this case, the robot must shut down and wait to be rescued (producing a low reward.) + +The agent makes its decisions solely as a function of the energy level of the battery, It can distinguish two levels, high and low, so that the state set is $\mathcal{S} = \{high, low\}$. Let us call the possible decisions -- the agent's actions -- wait, search, and recharge. When the energy level is high, recharging would always be foolish, so we do not include it in the action set for this state. The agent's action sets are +$$ +\begin{align*} +\mathcal{A}(high) &= \{search, wait\} \\ +\mathcal{A}(low) &= \{search, wait, recharge\} +\end{align*} +$$ +If the energy level is high, then a period of active search can always be completed without a risk of depleting the battery. A period of searching that begins with a high energy level leaves the energy level high with a probability of $\alpha$ and reduces it to low with a probability of $(1 - \alpha)$. On the other hand, a period of searching undertaken when the energy level is low leaves it low with a probability of $\beta$ and depletes the battery with a probability of $(1 - \beta)$. In the latter case, the robot must be rescued, and the batter is then recharged back to high. + +Each can collected by the robot counts as a unit reward, whereas a reward of $-3$ occurs whenever the robot has to be rescued. Let $r_{search}$ and $r_{wait}$ with $r_{search } > r_{wait}$, respectively denote the expected number of cans the robot will collect while searching and waiting. Finally, to keep things simple, suppose that no cans can be collected ruing a run home for recharging and that no cans can be collected on a step in which the battery is depleted. + +| $s$ | $a$ | $s^\prime$ | $p(s^\prime | s, a)$ | $r(s| +| ---- | -------- | ---------- | ------------- | ------------ | --- | +| high | search | high | $\alpha$ | $r_{search}$ | +| high | search | low | $(1-\alpha)$ | $r_{search}$ | +| low | search | high | $(1 - \beta)$ | -3 | +| low | search | low | $\beta$ | $r_{search}$ | +| high | wait | high | 1 | $r_{wait}$ | +| high | wait | low | 0 | $r_{wait}$ | +| low | wait | high | 0 | $r_{wait}$ | +| low | wait | low | 1 | $r_{wait}$ | +| low | recharge | high | 1 | 0 | +| low | recharge | low | 0 | 0 | + +A *transition graph* is a useful way to summarize the dynamics of a finite MDP. There are two kinds of nodes: *state nodes* and *action nodes*. There is a state node for each possible state and an action node for reach state-action pair. Starting in state $s$ and taking action $a$ moves you along the line from state node $s$ to action node $(s, a)$. The the environment responds with a transition ot the next states node via one of the arrows leaving action node $(s, a)$. + +![1537031348278](/home/rozek/Documents/Research/Reinforcement Learning/1537031348278.png) + +## Goals and Rewards + +The reward hypothesis is that all of what we mean by goals and purposes can be well thought of as the maximization of the expected value of the cumulative sum of a received scalar signal called the reward. + +Although formulating goals in terms of reward signals might at first appear limiting, in practice it has proved to be flexible and widely applicable. The best way to see this is to consider the examples of how it has been, or could be used. For example: + +- To make a robot learn to walk, researchers have provided reward on each time step proportional to the robot's forward motion. +- In making a robot learn how to escape from a maze, the reward is often $-1$ for every time step that passes prior to escape; this encourages the agent to escape as quickly as possible. +- To make a robot learn to find and collect empty soda cans for recycling, one might give it a reward of zero most of the time, and then a reward of $+1$ for each can collected. One might also want to give the robot negative rewards when it bumps into things or when somebody yells at it. +- For an agent to play checkers or chess, the natural rewards are $+1$ for winning, $-1$ for losing, and $0$ for drawing and for all nonterminal positions. + +It is critical that the rewards we set up truly indicate what we want accomplished. In particular, the reward signal is not the place to impart to the agent prior knowledge about *how* to achieve what we want it to do. For example, a chess playing agent should only be rewarded for actually winning, not for achieving subgoals such as taking its opponent's pieces. If achieving these sort of subgoals were rewarded, then the agent might find a way to achieve them without achieving the real goal. The reward signal is your way of communicating what you want it to achieve, not how you want it achieved. + +## Returns and Episodes + +In general, we seek to maximize the *expected return*, where the return is defined as some specific function of the reward sequence. In the simplest case, the return is the sum of the rewards: +$$ +G_t = R_{t + 1} + R_{t + 2} + R_{t + 3} + \dots + R_{T} +$$ +where $T$ is the final time step. This approach makes sense in applications in which there is a natural notion of a final time step. That is when the agent-environment interaction breaks naturally into subsequences or *episodes*, such as plays of a game, trips through a maze, or any sort of repeated interaction. + +### Episodic Tasks + +Each episode ends in a special state called the *terminal state*, followed by a reset to the standard starting state or to a sample from a standard distribution of starting states. Even if you think of episodes as ending in different ways the next episode begins independently of how the previous one ended. Therefore, the episodes can all be considered to ending the same terminal states with different rewards for different outcomes. + +Tasks with episodes of this kind are called *episodic tasks*. In episodic tasks we sometimes need to distinguish the set of all nonterminal states, denoted $\mathcal{S}$, from the set of all states plus the terminal state, denoted $\mathcal{S}^+$. The time of termination, $T$, is a random variable that normally varies from episode to episode. + +### Continuing Tasks + +On the other hand, in many cases the agent-environment interaction goes on continually without limit. We call these *continuing tasks*. The return formulation above is problematic for continuing tasks because the final time step would be $T = \infty$, and the return which we are trying to maximize, could itself easily be infinite. The additional concept that we need is that of *discounting*. According to this approach, the agent tries to select actions so that the sum of the discounted rewards it receives over the future is maximized. In particular, it chooses $A_t$ to maximize the expected discounted return. +$$ +G_t= \sum_{k = 0}^\infty{\gamma^kR_{t+k+1}} +$$ +where $\gamma$ that is a parameter between $0$ and $1$ is called the *discount rate*. + +#### Discount Rate + +The discount rate determines the present value of future rewards: a reward received $k$ time steps in the future is worth only $\gamma^{k - 1}$ time what it would be worth if it were received immediately. If $\gamma < 1$, the infinite sum has a finite value as long as the reward sequence is bounded. + +If $\gamma = 0$, the agent is "myopic" in being concerned only with maximizing immediate rewards. But in general, acting to maximize immediate reward can reduce access to future rewards so that the return is reduced. + +As $\gamma$ approaches 1, the return objective takes future rewards into account more strongly; the agent becomes more farsighted. + +### Example 3.5 Pole-Balancing + +The objective in this task is to apply forces to a car moving along a track so as to keep a pole hinged to the cart from falling over. + +A failure is said to occur if the pole falls past a given angle from the vertical or if the cart runs off the track. + +![1537500975060](/home/rozek/Documents/Research/Reinforcement Learning/1537500975060.png) + +#### Approach 1 + +The reward can be a $+1$ for every time step on which failure did not occur. In this case, successful balancing would mean a return of infinity. + +#### Approach 2 + +The reward can be $-1$ on each failure and zero all other times. The return at each time would then be related to $-\gamma^k$ where $k$ is the number of steps before failure. + + + +Either case the return is maximized by keeping the pole balanced for as long as possible. + +## Policies and Value Functions + +Almost all reinforcement learning algorithms involve estimating *value functions* which estimate what future rewards can be expected. Of course the rewards that the agent can expect to receive is dependent on the actions it will take. Accordingly, value functions are defined with respect to particular ways of acting, called policies. + +Formally, a *policy* is a mapping from states to probabilities of selecting each possible action. The *value* of a state s under a policy \pi, denoted $v_{\pi}(s)$ is the expected return when starting in $s$ and following $\pi$ thereafter. For MDPs we can define $v_{\pi}$ as + +$$ +v_{\pi}(s) = \mathbb{E}_{\pi}[G_t | S_t = s] = \mathbb{E}_{\pi}[\sum_{k = 0}^\infty{\gamma^kR_{t+k+1} | S_t = s}] +$$ + +We call this function the *state-value function for policy $\pi$*. Similarly, we define the value of taking action $a$ in state $s$ under a policy $\pi$, denoted as $q_\pi(s,a)$ as the expected return starting from $s$, taking the action $a$, and thereafter following the policy $\pi$. Succinctly, this is called the *action-value function for policy $\pi$*. + +### Optimality and Approximation + +For some kinds of tasks we are interested in,optimal policies can be generated only with extreme computational cost. A critical aspect of the problemfacing the agent is always teh computational power available to it, in particular, the amount of computation it can perform in a single time step. + +The memory available is also an important constraint. A large amount of memory is often required to build up approximations of value functions, policies, and models. In the case of large state sets, functions must be approximated using some sort of more compact parameterized function representation. + +This presents us with unique oppurtunities for achieving useful approximations. For example, in approximating optimal behavior, there may be many states that the agent faces with such a low probability that selecting suboptimal actions for them has little impact on the amount of reward the agent receives. + +The online nature of reinforcement learning which makes it possible to approximate optimal policies in ways that put more effort into learning to make good decisions for frequently encountered states at the expense of infrequent ones is the key property that distinguishes reinforcement learning from other approaches to approximately solve MDPs. + +### Summary + +Let us summarize the elements of the reinforcement learning problem. + +Reinforcement learning is about learning from interaction how to behave in order to achieve a goal. The reinforcement learning *agent* and its *environment* interact over a sequence of discrete time steps. + +The *actions* are the choices made by the agent; the states are the basis for making the choice; and the *rewards* are the basis for evaluating the choices. + +Everything inside the agent is completely known and controllable by the agent; everything outside is incompletely controllable but may or may not be completely known. + +A *policy* is a stochastic rule by which the agent selects actions as a function of states. + +When the reinforcement learning setup described above is formulated with well defined transition probabilities it constitutes a Markov Decision Process (MDP) + +The *return* is the function of future rewards that the agent seeks to maximize. It has several different definitions depending on the nature of the task and whether one wishes to *discount* delayed reward. + +- The un-discounted formulation is appropriate for *episodic tasks*, in which the agent-environment interaction breaks naturally into *episodes* +- The discounted formulation is appropriate for *continuing tasks* in which the interaction does not naturally break into episodes but continue without limit + +A policy's *value functions* assign to each state, or state-action pair, the expected return from that state, or state-action pair, given that the agent uses the policy. The *optimal value functions* assign to each state, or state-action pair, the largest expected return achievable by any policy. A policy whose value unctions are optimal is an *optimal policy*. + +Even if the agent has a complete and accurate environment model, the agent is typically unable to perform enough computation per time step to fully use it. The memory available is also an important constraint. Memory may be required to build up accurate approximations of value functions, policies, and models. In most cases of practical interest there are far more states that could possibly be entries in a table, and approximations must be made. + + + + diff --git a/content/research/reinforcementlearning/readings.md b/content/research/reinforcementlearning/readings.md new file mode 100644 index 0000000..5243255 --- /dev/null +++ b/content/research/reinforcementlearning/readings.md @@ -0,0 +1,19 @@ +# Readings for Lectures of Cluster Analysis + +## Lecture 1 +Chapter 1: What is Reinforcement Learning? + +## Lecture 2 +Chapter 2: Multi-armed Bandits + +## Lecture 3 +Chpater 3: Finite Markov Decision Processes Part 1 + +## Lecture 4 +Chapter 3: Finite Markov Decision Processes Part 2 + +## Lecture 5 +[No Readings] Playing around with Multi-armed Bandits Code + + +**Lost track of readings around this time period :(** diff --git a/content/research/reinforcementlearning/syllabus.md b/content/research/reinforcementlearning/syllabus.md new file mode 100644 index 0000000..6cea733 --- /dev/null +++ b/content/research/reinforcementlearning/syllabus.md @@ -0,0 +1,78 @@ +# Reinforcement Learning + +The goal of this independent study is to gain an introduction to the topic of Reinforcement Learning. + +As such the majority of the semester will be following the textbook to gain an introduction to the topic, and the last part applying it to some problems. + + +## Textbook + +The majority of the content of this independent study will come from the textbook. This is meant to lessen the burden on the both us of as I already experimented with curating my own content. + +The textbook also includes examples throughout the text to immediately apply what's learned. + +Richard S. Sutton and Andrew G. Barto, "Reinforcement Learning: An Introduction" http://incompleteideas.net/book/bookdraft2017nov5.pdf + +## Discussions and Notes + +Discussions and notes will be kept track of and published on my tilda space as time and energy permits. This is for easy reference and since it's nice to write down what you learn. + +## Topics to be Discussed + +###The Reinforcement Learning Problem (3 Sessions) + +In this section we will get ourselves familiar with the topics that are commonly discussed in Reinforcement learning problems. + +In this section we will learn the different vocab terms such as: + +- Evaluative Feedback +- Non-Associative Learning +- Rewards/Returns +- Value Functions +- Optimality +- Exploration/Exploitation +- Model +- Policy +- Value Function +- Multi-armed Bandit Problem + +### Markov Decision Processes (4 Sessions) + +This is a type of reinforcement learning problem that is commonly studied and well documented. This helps form an environment for which the agent can operate within. Possible subtopics include: + +- Finite Markov Decision Processes +- Goals and Rewards +- Returns and Episodes +- Optimality and Approximation + +### Dynamic Programming (3 Sessions) + +Dynamic Programming refers to a collection of algorithms that can be used to compute optimal policies given an environment. Subtopics that we are going over is: + +- Policy Evaluation +- Policy Improvement +- Policy Iteration +- Value Iteration +- Asynchronous DP +- Generalized policy Iteration +- Bellman Expectation Equations + +### Monte Carlo Methods (3 Sessions) + +Now we move onto not having complete knowledge of the environment. This will go into estimating value functions and discovering optimal policies. Possible subtopics include: + +- Monte Carlo Prediction +- Monte Carlo Control +- Importance Sampling +- Incremental Implementation +- Off-Policy Monte Carlo Control + +### Temporal-Difference Learning (4-5 Sessions) + +Temporal-Difference learning is a combination of Monte Carlo ideas and Dynamic Programming. This can lead to methods learning directly from raw experience without knowledge of an environment. Subtopics will include: + +- TD Prediction +- Sarsa: On-Policy TD Control +- Q-Learning: Off-Policy TD Control +- Function Approximation +- Eligibility Traces diff --git a/content/ta.md b/content/ta.md new file mode 100644 index 0000000..9c539de --- /dev/null +++ b/content/ta.md @@ -0,0 +1,28 @@ +--- +title: Teaching Assistant +description: My work as a teaching assistent +--- + + +## Dr. Jessica Zeitz-Self +I was the lab aide for Dr. Zeitz' Computer Programming and Problem Solving (CPSC 220). + +My role in this class was to help students during lab time and to create lecture notes based on the lectures given in class. + +[Spring 2018/CPSC 220 Notes](spring2018/cpsc220) + +## Dr. Jennifer Polack + +I've been the lab aide for two of Polack's classes so far: Introduction to Computer Science (CPSC 110) and Computer Programming and Problem Solving (CPSC 220). + +My role involves helping students debug during the lab time. I also create lecture notes for students to look over while working on projects. + +[Summer 2017/CPSC 110 Notes](summer2017/cpsc110) + +[Fall 2017/CPSC 220 Lecture Notes](fall2017/cpsc220) + +## Dr. Ron Zacharski + +I was the lab aide for Zacharski's DATA 101 class. My role in his class mostly involved helping students debug during lab time and grading student's demonstrations of what they've done in a lab. + +He also asked me to TA for the NVIDIA Computer Vision workshop that he was running at the University. diff --git a/content/ta/_index.md b/content/ta/_index.md new file mode 100644 index 0000000..e69de29 diff --git a/content/ta/fall2017/cpsc220.md b/content/ta/fall2017/cpsc220.md new file mode 100644 index 0000000..53b1b81 --- /dev/null +++ b/content/ta/fall2017/cpsc220.md @@ -0,0 +1,39 @@ +# CPSC 220 Computer Programming and Problem Solving Fall 2017 + +[Lecture 3 -- September 6](sept6) + +[Lecture 4 -- September 11](sept11) + +[Lecture 7 -- September 20](sept20) + +[Lecture 9 -- September 25](sept25) + +[Lecture 10 -- October 2](oct2) + +[Lecture 11 -- October 4](oct4) + +[Lecture 12 -- October 9](oct9) + +[Lecture 13 -- October 11](oct11) + +[Lecture 15 -- October 18](oct18) + +[Lecture 16 -- October 23](oct23) + +[Lecture 17 -- October 25](oct25) + +[Lecture 18 -- October 30](oct30) + +[Exam 2 Review -- October 30](exam2review) + +[Lecture 19 -- November 6](nov6) + +[Lecture 20 -- November 13](nov13) + +[Lecture 21 -- November 15](nov15) + +[Lecture 22 -- November 20](nov20) + +[Lecture 23 -- November 27](nov27) + +[Lecture 25 -- December 6](dec6) diff --git a/content/ta/fall2017/cpsc220/dec6.md b/content/ta/fall2017/cpsc220/dec6.md new file mode 100644 index 0000000..b1de303 --- /dev/null +++ b/content/ta/fall2017/cpsc220/dec6.md @@ -0,0 +1,125 @@ +# Final Review December 6 + +## Classes + +Here is how you can create a class called "Employee" with a non-default constructor (a constructor that takes parameters) and a getter and setter + +```java +public class Employee { + // Our private variables + private String name; + private double salary; + // Non-default constructor + public Employee(String name, double salary) { + this.name = name; + this.salarly = salary; + } + // This is a getter + public string getName() { + return name; + } + public double setSalarly(double salary) { + this.salary = salary; + } +} +``` + +## For Loops + Arrays + +For loops are constructed in the following way + +`for (initialization; condition to stop; increment to get closer to condition to stop)` + +```java +//Assume an array with variable name array is declared before +for (int i = 0; i < array.length; i++) { + // This code will loop through every entry in the array +} +``` + +Note that you don't always have to start from zero, you can start anywhere from the array. + +## For Loops + Arrays + Methods + +This is an example of how you can take in an array in a method + +```java +public static boolean isEven(int[] array) { // <-- Note the int[] array + for (int i = 0; i < array.length; i++) { // Iterate through the entire array + // If you find an odd number, return false + if (array[i] % 2 == 1) { + return false; + } + } + // If you didn't find any odd numbers, return true + return true; +} +``` + +## File I/O + +Let's say that you have the following file + +``` +4 +chicken +3 +salad +``` + +And you want to make it so that you take the number, and print the word after it a certain number of times. For this example we would want to see the following + +```java +chicken chicken chicken chicken +salad salad salad +``` + +Here is the code to write it + +```java +public static void printStrings() { + FileInputStream file = new FileInputStream("stuff.txt"); // File contents are in stuff.txt + Scanner scnr = new Scanner(file); // Scanner takes in a file to read + while (scnr.hasNext()) { // While there are still stuff in the file to read + int number = scnr.nextInt(); // Grab the number + String word = scnr.next(); // Grab the word after the number + // Print the word number times + for (int i = 0; i < number; i++) { + System.out.print(word); + } + // Put a new line here + System.out.println(); + } + +} +``` + +## Recursion + +Look at handout and carefully trace recursion problems + +## 2D Arrays + +Declare a 2D int array with 4 rows and 7 columns + +```java +int[][] dataVals = new int[4][7]; +``` + +A 2D array with 4 rows and 7 columns has 7 * 4 = 28 entries. + + + +If you want to sum up all the numbers in a 2 dimensional array, do the following + +``` java +// Assume numbers is declared beforehand +int sum = 0; +for (int i = 0; i < numbers.length; i++) { // Loop through every row in the 2D array + for (int j = 0; j < numbers[i].length; j++) { // Loop through every column in a row + // This code now looks at one entry in a 2D array + sum += numbers[i][j]; + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/exam2review.md b/content/ta/fall2017/cpsc220/exam2review.md new file mode 100644 index 0000000..e6acf9d --- /dev/null +++ b/content/ta/fall2017/cpsc220/exam2review.md @@ -0,0 +1,62 @@ +# Exam Review Partial Answer Sheet + +Write a Java method to sum values of an array + +```java +// Assume variable numbers is an array of 10 integers +int sum = 0; +for (int i = 0; i < numbers.length; i++) { + sum += numbers[i]; +} +``` + +Write a Java method to test if an array contains a specific value + +```java +// Assume variable numbers is an array of 10 integers +int numWanted = 4; +boolean found = false; +for (int i = 0; i < numbers.length; i++) { + if (numbers[i] == numWanted) { + System.out.println("The number " + numWanted + " was found!"); + found = true; + } +} +if (!found) { + System.out.println("The number " + numWanted + " was not found!"); +} +``` + +Write a Java method to find the index of an array element + +```java +// Assume variable numbers is an array of 10 integers +int numWanted = 4; +boolean found = false; +for (int i = 0; i < numbers.length; i++) { + if (numbers[i] == numWanted) { + System.out.println("The index of number " + numWanted + " is " + i); + } +} +``` + +How many lines will the following loop print when it is run? + +```java +int i = 0; +while (i <= 6) { + System.out.println("i is now " + (i)); + i++; +} +``` + +``` +i is now 0 +i is now 1 +i is now 2 +i is now 3 +i is now 4 +i is now 5 +i is now 6 +``` + diff --git a/content/ta/fall2017/cpsc220/nov13.md b/content/ta/fall2017/cpsc220/nov13.md new file mode 100644 index 0000000..028152e --- /dev/null +++ b/content/ta/fall2017/cpsc220/nov13.md @@ -0,0 +1,221 @@ +# Lecture for November 13 + +## File IO (Cont.) + +Last class we talked about reading from files, we can also write to files. + +### Import necessary libraries + +First you must import all of the necessary libraries + +```java +// To read +import java.util.Scanner; +import java.io.FileOutputStream; +// To Write +import java.io.FileReader; +import java.io.PrintWriter; +// For Exception Handling +import java.io.IOException; +``` + +Then in your main, declare a `FileOutputStream` and `PrintWriter` + +```java +FileOutputStream file; +PrintWriter print; +``` + +### Try-Catch-Finally + +Create a try block to open a file for writing + +```java +try { + // If the file doesn't exist, it'll create it + file = new FileOutputStream("output.txt"); + print = new PrintWriter(file); +} catch (IOException except) { + // Prints out the error message + System.out.println("File error " + except.getMessage()); +} +``` + +Adding a finally block allows the program to clean up before it closes + +```java + try { + file = new FileOutputStream("output.txt"); + print = new PrintWriter(file); + } catch (IOException except) { + System.out.println("File error " + except.getMessage()); + } finally { // It starts here! + delete file; + delete print; + file.close(); + return; + } +``` + +### Write to the file :) + +Then you can write the to file! + +```java +// Do you notice the following methods? + print.println("Your number is"); + print.print("My name is..\n"); + print.printf("%s %d", "Hello ", 5); + print.flush(); //Clears the output stream + file.close(); //Closes the file + +``` + +Extra Note: Disk fragmentation is a way of cleaning up memory that isn't being used by any of the code on your computer. + +## Swing Graphics + +### Importing Necessary Libraries + + + +You need to import all the necessary libraries first + +```java +import javax.swing.*; +import java.awt.FlowLayout; +import java.awt.event.ActionListener; +``` + +### Changing the class header + +Your class file needs to extend `JFrame` that way it can use a bunch of the already existent code written for Swing applications + +```java +public class firstGUi extends JFrame { + //.... +``` + +### Swing Components + +Java Swing makes use of what is called Swing Components. These are basic building blocks of GUI items you can add to the screen. For example, a checkbox, a radio button, text field. These are all swing components. + +I wrote a blog post back in the summer which is an overview of them. You can check it out here: https://brandonrozek.com/2017/06/java-swing-components/ + +Inside your `firstGUI` class, declare some Swing components you would like to use in the program + +```java +public class firstGUI extends JFrame { + JButton button1; + JTextArea area; + JTextField text; + // .... + +``` + +### Constructor + +You need to create a constructor for this class that way you can initiate all of the swing component values. + +```java +// ... +JButton button1; +JTextArea area; +JTextField text; + +// Begin Constructor +firstGUI() { + // Define the components + JLabel name = new JLabel("Enter in your name:"); + text = new JTextField("Jennifer", 20); // 20 characters long, default value: Jennifer + area = new JTextArea(10, 10); //Width and Height is 10 characters big + JScrollPane sp = new JScrollPane(area); //Adds a scroll bar for the text area + button1 = new JButton("Press Me"); + + // Set the Layout + // FlowLayout organizes each of the components top to bottom, left to right + setLayout(new FlowLayout()); + + // Add the components to the screen + add(name); + add(text); + add(sp); // never add the textarea when surrounded by a ScrollPane + add(button1); +} +``` + +### New Main Method + +Finally, you need to create the Main method which will initiate it all + +```java +public static void main(String[] args) { + firstGUI myFrame = new firstGUI(); + + // End the program when the 'x' button (not keyboard) is pressed + myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + myFrame.setTitle("My title"); // Titles the window + myFrame.pack(); // Packs it all into the frame + myFrame.setVisible(true); // Makes the frame appear on the screen +} +``` + +### Making it interactive + +You need to change your class header to the following + +```java +public class firstGUI extends JFrame implements ActionListener { + // ... +``` + +Then in your class, add the following method + +```java +@Override public void actionPerformed(ActionEvent event) { + // Do stuff as a result of an event here + area.append("You Pressed the Button"); +} +``` + +To make it actually activate as a result of an event. You need to attach it to a swing component. + +For example, I want the code in `actionPerformed` to activate in result of a button press. + +Add the following line to your code in the constructor. + +```java +//... +button1 = new JButton("Press Me"); +button1.addActionListener(this); // New Code +//.... +``` + + + +### Identifying Button Pressed + +How do you know which button was pressed in the `actionPerformed` method? + +You can use `event.getSource()` to find out. + +Example: + +```java +@Override public void actionPerformed(ActionEvent event) { + if (event.getSource() == button1) { // Replace button1 with appropriate variable name + // Do things as a result of a specific button being pressed + } +} +``` + +### Summary + +To use Swing, do the following steps + +1. Import Libraries +2. Declare J___ variables +3. New the J___ variables +4. Add the J___ variables to the frame +5. Add the `ActionListener` to the components you wish to monitor \ No newline at end of file diff --git a/content/ta/fall2017/cpsc220/nov15.md b/content/ta/fall2017/cpsc220/nov15.md new file mode 100644 index 0000000..2aa309f --- /dev/null +++ b/content/ta/fall2017/cpsc220/nov15.md @@ -0,0 +1,109 @@ +# Lecture Notes for November 15th + +Import the necessary libraries + +```java +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +``` + +This time we'll be using the null layout. This will require you to set the x, and y positions of each of the elements on the screen + +First we'll make a class called `GUILayout` which will extend `JPanel` and contain our layout and components + +```java +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class GUILayout extends JPanel { + private JButton one, two; + private JTextField text; + private JTextArea area; + private int count; // Used to keep track of button pushes + private int number = 0; + + GUILayout() { + // Set the layout to the null layout + setLayout(null); + // Tells the computer that you wish to have the size of your program to be 500x500 + setPreferredSize(new Dimension(500, 500)); + + // Create the buttons + one = new JButton("Change color"); + two = new JButton("Count Pushes"); + + // Set the x, y, width, height inside parenthesis + // This places the buttons on the specified locations on the screen + one.setBounds(10, 10, 100, 24); + two.setBounds(120, 10, 100, 24); + + // Sets the color of the text of button 1 to blue + one.setForeground(Color.BLUE); + + // Add the components to the screen + add(one); + add(two); + + + text = new JTextField("Today is Wednesday, a photographer is here."); + text.setBounds(10, 40 ,480, 24); + add(text); + + area = new JTextArea(20, 20); + // Wrap the text area into the scroll pane + // This adds the scroll bars (vertical/horizontal) + JScrollPane sp = new JScrollPane(area); + sp.setBounds(10, 75, 490, 400); + add(sp); + + // Bind the Listener class to the button one + one.addActionListener(new Listener()); + + // Bind it to two and text + two.addActionListener(new Listener()); + text.addActionListener(new Listener()); + + } + + // Create the class for the listener + private class Listener implements ActionListener { + // Define what you want to occur after an event + public void actionPerformed(ActionEvent event) { + if (event.getSource() == one) { + + } else if (event.getSource() == two) { + count++; + // \n is needed to prevent scrolling + area.append("You pressed the button " + count + " times!"); + } else if (event.getSource() == text) { + // Grab the number inside the text area and set it to the variable number + number = Integer.paseInt(text.getText()); + number += 10; + // add "" to number so that it converts number to a String + text.setText(number + ""); + // Convert the number to a String + String temp = Integer.toString(number); + area.setText(temp); + } + + + } + } +} +``` + +The main code is really short, you just need to extend `JFrame` and some short code seen last class to set it up. + +```java +public class mainTester extends JFrame { + public static void main(String[] args) { + JFrame frame = new JFrame("Sample GUI"); // Sets the title to "Sample GUI" + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // Instantiate the GUILayout file you made before + frame.getContentPane().add(new GUILayout()); + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/nov20.md b/content/ta/fall2017/cpsc220/nov20.md new file mode 100644 index 0000000..77f2ce6 --- /dev/null +++ b/content/ta/fall2017/cpsc220/nov20.md @@ -0,0 +1,116 @@ +# Lecture for November 20 + +## Adding a drawing panel to the GUI + +You can't put swing and graphics together, therefore you need to make a seperate JPanels for swing and graphics. + +Add necessary libraries + +```java +import java.awt.*; +import java.awt.Graphics; +import java.awt.event.*; +import javax.swing.*; +``` + + + +```java +public class drawingWindow extends JPanel { + JTextField field; + JButton draw; + DrawingPanel drawingPanel; + + public drawingWindow() { + // Each new component would be vertically stacked upon each other + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + JPanel swingSTuff = new JPanel(); + + // Add things to the screen + draw = new JButton("Draw"); + field = new JTextField(); + swingStuff.add(field); + swingStuff.add(draw) + + // Add the drawing panel onto the screen + drawingPanel = new DrawingPanel(200, 400); + add(drawingPanel); + + // Activate the listener if the button was pressed + draw.addActionListener(new Listener()); + } + + // Add the listener to respond to events + private class listener implements ActionListener { + public void actionPerformed(ActionEvent event) { + if (event.getSource() == draw) { + drawingPanel.setFlag(1); + // Repaints the screen so the oval can appear + drawingPanel.repaint(); + } + } + } + + // Create the draw panel so we can add it to the screen + private class DrawingPanel extends JPanel { + private int width, height; + DrawingPanel(int width, int height) { + this.width = width; + this.height = height; + setPreferredSize(new Dimension(width, height)); + } + public void setFlag(int flag) { + this.flag = flag; + } + public void paintComponent(Graphics g) { + super.paintComponent(g); + + // Every time the flag is set, draw an oval at a random location and color + if (flag == 1) { + Random rand = new Random(); + int x = rand.nextInt(width); + int y = rand.nextInt(height); + g.setColor(Color.RED); + g.fillOval(x, y, 20, 30); + } + } + } +} +``` + +There are a myriad of different methods you can use. + +```java +// Assume width, height, y, x, etc are defined above +public void paintComponent(Graphics g) { + //.... + g.dispose(); // Flushes the graphics buffer +} +``` + +You have the traditional fill and draw methods. Fill creates the shape shaded in with a color. Draw creates an outline of the shape. + +```java + +// ... +g.fillRect(x ,y, width, height); + g.drawRect(x, y, width, height); + g.fillOval(x, y, width, height); + g.drawOval(x, y, width, height); + //g.drawPoly(parematers...); + //g.fillPoly(parameters...); + g.drawArc(x, y, width, height, startingAngle, sweepingAngle); + g.fillArc(x, y, width, height, startingAngle, sweepingAngle); +``` + +You can also create complex shapes like a polygon. When adding points, you need to make sure you add them Clockwise or Counterclockwise (but NOT both) + +```java + Polygon tri = new Polygon(); + tri.addPoint(150, 10); + tri.addPoint(175, 100); + tri.addPoint(125, 100); + // Add points clockwise or counterclockwise (NOT BOTH) +``` + diff --git a/content/ta/fall2017/cpsc220/nov27.md b/content/ta/fall2017/cpsc220/nov27.md new file mode 100644 index 0000000..fc94189 --- /dev/null +++ b/content/ta/fall2017/cpsc220/nov27.md @@ -0,0 +1,267 @@ +# Lecture for November 27 + +## Recursion + +When doing recursion, make sure not to use loops. + +Recursion is when a function makes a function call to itself. + +It consists of two parts: + +- Base Case: This tell it when to stop +- Smaller Caller Case: Helps you get closer to the base case + +You can have one or more base cases or caller cases. + +To teach recursion, we'll start with a problem that should be written iteratively (with loops) but we'll show how to do it with recursion. + +### Example: Counting Down + +```java +void CountDown(int number) { + while (number > 0) { + System.out.println(number + " "); + number = number - 1; + } + System.out.println("Blast Off") +} +``` + +1. How does this loop stop? -- Base Case +2. How does this loop change each time through? -- Smaller caller case + +Base Case: It stops when the number equals 0 + +```java +// Base Case +if (number == 0) { + System.out.println("Blast Off"); + return; +} +``` + +Smaller Caller Case: It decreases number by 1 + +```java +// Smaller Caller Case +System.out.print(number + " "); +countDownRecursive(number - 1); +``` + +Put it together... + +```java +void countDownRecursive(int number) { + if (number == 0) { + System.out.println("Blast Off"); + } else { + System.out.print(number + " "); + countDownRecursive(number - 1); + } +} +``` + +Prints `10 9 8 7 6 5 4 3 2 1 Blast Off` + +### Stack Snapshots + +Every time you make a recursive call, it keeps track of all the local variables at the current function call and pushes it onto the stack. + +That means if you make 10 recursive calls, you'll have 10 slots added onto the stack. If you want to return back to the beginning, you would need to return 10 times. + +### Order Matters + +Whether you do the recursive step first or some other action, it completely changes the output. Look at the following example that's similar to `countDownRecursive`. + +```java +void countUpRecursive(int number) { + if (number == 0) { + System.out.println("Blast Off"); + } else { + // Notice the swapping of the next two lines + countUpRecursive(number - 1); + System.out.print(number + " "); + } +} +``` + +This would print out `Blast Off 1 2 3 4 5 6 7 8 9 10` + +### Example: Summing up to a number + +This would be our iterative solution + +```java +int sum(int number) { + int sum = 0; + while (number > 0) { + sum += number; + number--; + } + return sum; +} +``` + +How does this loop stop? + +​ Same as before. Think about it, if the number you pass in is zero, what should be the result of sum? Zero. Since adding up from 0 to 0 is just 0. + +```java +if (number == 0) { + return 0; +} +``` + +How does this loop change each time through? + +​ You want to update your sum, so return the sum of the next call to the current sum. + +```java +return (number + sum(number - 1)); +``` + +Putting it all together + +```java +int sumRecursive(int number) { + if (number == 0) { + return 0; + } else { + return number + sumRecursive(number - 1); + } +} +``` + +### Example: Linear Search + +How to do it iteratively. + +```java +void linearSearch(int[] array, int number) { + int i = 0; + while (i < array.length && number != array[i]) { + i++; + } + if (i == array.length) { + System.out.println("Not Found"); + } else { + System.out.println("Found"); + } +} +``` + +Base Case: There are two base cases, when it reaches the end of the array and when it finds the number + +```java +if (array.length == i) { + System.out.println("Not Found"); +} else (array[i] == number) { + System.out.println(number + " found at index " + i); +} +``` + +Smaller Caller Case: Check the next element + +```java +linearSearchRecursion(number, array, i + 1); +``` + +Putting it all together... + +```java +void linearSearchRecursion(int[] array, int number) { + if (array.length == i) { + System.out.println("Not Found"); + } else if (array[i] == number) { + System.out.println(number + " found at index " + index); + } else { + linearSearchRecursion(number, array, i + 1); + } +} +``` + +## Binary Search + +This is a much more efficient search than the linear search we have been doing. The only condition is that your array must be sorted beforehand. + +A regular linear search `O(n)` -- Check at most all of the elements of the array. + +Binary Search `O(log(n))` -- Checks at most `ceil(log(n))` elements of an array. + +To demonstrate this with real numbers, let's take an array of 100 elements + +- With linear search this will take at most 100 iterations +- With binary search this will take at most **7**. + +Crazy right? + + + +### Implementation + +**Iterative approach** + +```java +void binarySearch(int number, int[] array) { + int lower = 0; + int upper = array.length - 1; + int mid = (lower + upper) / 2 + while (lower <= upper && array[mid] != number) { + mid = (lower + upper) / 2; + if (array[mid] < number) { + lower = mid + 1; + } else if () { + upper = mid -1; + } + } + if (lower > upper) { + System.out.println("Not Found"); + } else { + System.out.println(number + " found at index " + mid); + } +} +``` + +**Recursive Approach** + +Base Case: There are two cases, you either found it, or you made it to the end of the array without finding it + +```java +if (lower > upper) { + System.out.println("Not Found"); +} else if (array[mid] == number) { + System.out.println(number + " found at index " + mid); +} +``` + +Smaller Caller Case: Change the lower or upper bounds to cut the search in half + +```java +if (array[mid] < number) { + lower = mid + 1; + binarySearchRecursive(number, array, lower, upper); +} else if (array[mid] > number) { + upper = mid - 1; + binarySearchRecursive(number, array, lower, upper); +} +``` + +Putting it together.... + +```java +binarySearch(int number, int[] array, int lower, int upper) { + if (lower > upper) { + System.out.println("Not Found"); + } else if (array[mid] == number) { + System.out.println(number + " found at index " + mid); + } + else if (array[mid] < number) { + lower = mid + 1; + binarySearchRecursive(number, array, lower, upper); + } else if (array[mid] > number) { + upper = mid - 1; + binarySearchRecursive(number, array, lower, upper); + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/nov6.md b/content/ta/fall2017/cpsc220/nov6.md new file mode 100644 index 0000000..9c6c08a --- /dev/null +++ b/content/ta/fall2017/cpsc220/nov6.md @@ -0,0 +1,137 @@ +# November 6th Lecture + +## Compare cont. + +Continuing from last week's topic, writing a function called `compare` in your custom class. + +For example, for your project: + +```java +public bool compare(ResearchProject right, int type) { + if (type == 0) { // Is last lastname greater than right lastname alphabeticallly + if (lastname.compareTo(right.lastname) > 0) { + return true; + } else { + return false; + } + } else if (type == 1) { // Implement a different type of comparison + + } +} +``` + +You can then use the sorting algorithms discussed previously to sort the ResearchProjects using the `compare` method. + +## File IO + +First start by importing the required libraries. + +```java +import java.io.FileInputStream; +import java.io.IOException; // For error handling +import java.io.FileNotFoundException; // For error handling +import java.util.Scanner; +``` + +Then inside your main method which throws an IOException (see example "Reading the filename from the keyboard") + +```java +FileStream file; +Scanner in; +try { // Try something + file = new FileInputStream("test.txt"); + in = new Scanner(file); +} catch (FileNotFoundException e) { // Catch IF it fails + System.out.println("File not found."); + in = new Scanner(System.in); // Read from the keyboard instead +} +// Read the file now.... +String name = in.nextLine(); +``` + +Before we had linked the Scanner to the keyboard, now we're doing it to a file. + +### Try-Catch + +In the code above you see what's called a try-catch block. That means that if something was to happen in the execution of the code. Instead of just crashing as we have been seeing normally. We can deal with the error. In the example above you saw that the program reads from the keyboard instead of the file + +### Reading the filename from the keyboard + +```java +public static void main(String[] args) throws IOException { + FileInputStream file; + Scanner in, scnr; + // Connect one scanner to the keyboard to get the filename + scnr = new Scanner(System.in); + + System.out.print("Enter file name: "); + String filename = in.nextLine(); + + // Repeat code from previous example + FileStream file; + Scanner in; + try { + file = new FileInputStream(filename); // Only this line changed + in = new Scanner(file); + } catch (FileNotFoundException e) { + System.out.println("File not found."); + in = new Scanner(System.in); + } + String name = in.nextLine(); + // .... +} +``` + +The main throws the IOException since we don't deal with it in any of the catch blocks. + + + +### Reading names of people from a file into an array + +Let's say we have a file with the following in it + +``` +3 +Paul +Peter +Mary +``` + +3 is to indicate the number of names in th file. + +Let's write code in order to read these names into an array! + +```java +import java.io.FileInputStream; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.util.Scanner; +public static void main(String[] args) throws IOException { + FileInputStream file; + Scanner in, scnr; + scnr = new Scanner(System.in); + + System.out.print("Enter file name: "); + String filename = in.nextLine(); + + FileStream file; + Scanner in; + try { + file = new FileInputStream(filename); // Only this line changed + in = new Scanner(file); + } catch (FileNotFoundException e) { + System.out.println("File not found."); + in = new Scanner(System.in); + } + + // For the size of the array, get the first number in the file + int size = in.nextInt(); + String[] nameArray = new String[size]; + for (int i = 0; i < size; i++) { + namesArray[i] = in.nextLine(); + } + + // Now all the names in the file is in the namesArray +} +``` + diff --git a/content/ta/fall2017/cpsc220/oct11.md b/content/ta/fall2017/cpsc220/oct11.md new file mode 100644 index 0000000..a306568 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct11.md @@ -0,0 +1,133 @@ +# Lecture Notes October 11 + +## Global Variables + +Global variables is where you don't declare a variable inside a method. This is generally not a recommended practice. It is recommended to declare variables inside methods so that it is easier to reuse code. + +```java +public class mainDriver { + public static int globalVariable = 5; // I am a global variable + public static void main(String[] args) { + int localVariable = 4; // I am a local variable + } +} +``` + +## String Formatting + +You can format strings in java by using the `printf` method in System.out. + +Format strings work by using placeholders starting with `%` to specify where to place the value of a variable. + +General format of command + +```java +//System.out.printf(FormatString, variable1, variable2, ....) +String s = "The number is"; +int x = 5; +System.out.printf("%s %d", s, x); // Prints "The number is 5" +``` + +If you want to print out money, you can do it through the following + +```java +float tax = 0.45698; +System.out.printf("The tax is %.2f"); //prints "The tax is 0.46" +``` + +## Floating point precision + +Due to how computers store non-integers, math can be non-precise after some mathematical operations. It is therefore advantageous to do operations on integers to the level of precision you want. + +For example, instead of working in dollars, work in pennies since it's the smallest division we care about. + + + +### ArrayList + +Standard arrays are static, meaning they have no ability to grow. Instead of doing the operations we described last class, in order to add something to an array. We can use something called an `ArrayList` instead. + +The methods in the `ArrayList` library are useful abstractions to make the life of a programmer easier. + +ArrayLists can also hold only one type. The type cannot be a primitive like a standard array. Instead it must be a class representing the desired type. + +int -> Integer + +double -> Double + +char -> Character + +float -> String + +To declare and initialize an `ArrayList` + +```java +import java.util.ArrayList; +public class ArrayListTest { + public static void main(String[] args) { + ArrayList numbers = new ArrayList(); + ArrayList names = new ArrayList(); + } +} +``` + +`ArrayList`s has a variety of different methods that can be used to access/manipulate it + +- get +- set +- add +- clone +- clear +- size + +If you want to add the numbers 1 through 10 into the `ArrayList` of numbers + +```java +for (int i = 1; i < 11; i++) { + numbers.add(i); +} +``` + +To print out the entire contents of the `ArrayList` + +```java +for (int i = 0; i < numbers.size(); i++) { + System.out.println(numbers.get(i)); +} +``` + +How can you replace a value? + +```java +int n = 5; // Make this the number you wish to replace +int i = 0; +while (i < numbers.size() && numbers.get(i) != n) { + i++; +} +if (i == numbers.size()) { + System.out.println(n + " not found."); +} else { + int r = 10; // Make this the value you want to replace n with + numbers.set(i, r); +} +``` + +The `remove` method removes an item given an index. This shifts all the elements above the removed index down. + +```java +numbers.remove(3); // Removes the element in the third index +``` + +The `add` method can also take an index. It pushes all the elements at the index specified up. + +```java +numbers.add(3, 5); // Adds the number 5 to the third index +``` + +You can clone an array using the `clone` method + +```java +ArrayList numbers2 = new ArrayList(); +numbers2.clone(numbers); // Clones numbers into numbers2 +``` + diff --git a/content/ta/fall2017/cpsc220/oct18.md b/content/ta/fall2017/cpsc220/oct18.md new file mode 100644 index 0000000..0eaf04b --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct18.md @@ -0,0 +1,75 @@ +# October 18th + +## ArrayLists in classes + +```java +public class Numbers { + private ArrayList used; + private ArrayList unused; + numbers () { + // Debug: System.out.println("1. Constructor Entry Point"); + used = new ArrayList(); + unused = new ArrayList(); + // Debug: System.out.println("2, Constructor Size of ArrayLists" + used.size() + " " + unused.size()) + } + // Adds the numbers 1-5 into the used ArrayList + public void fillUsedArrayList() { + for (int i = 0; i < 5; i++) { + used.add(i + 1); + } + } + // Move an item from the unused ArrayList to the used ArrayList + public int moveIt(int index) { + int temp = used.get(index); + unused.add(temp); + // Debug: System.out.println("Adding to used array:" + (i + 1)); + used.remove(index); + return temp; + } + // The method below is created for debugging purposes + public void printBothArrayLists() { + // Print the used arraylist + System.out.println("Used ArrayList"); + for (int i = 0; i < used.size(); i++) { + System.out.println(used.get(i)); + } + + // Print the unused arraylist + System.out.println("Unused ArrayList"); + for (int i = 0; i < unused.size(); i ++) { + System.out.println(unused.get(i)); + } + } +} +``` + +Recall that you can compile the code above but you cannot run it. To run code, you must have a main method. + +## NumberTester + +```java +public class NumberTester { + public static void main(String[] args) { + Numbers list; + list = new Numbers(); + list.fillUsedArrayList(); + list.printBothArrayLists(); + } +} +``` + + + + + +## Difference between Array and ArrayList + +An Array is a **static** structure of contiguous memory of a single type. + +An ArrayList is a **dynamic** structure of contiguous memory of a single type + + + +To get the size of an array you use `.length` + +To get the size of an ArrayList you use `.size()` \ No newline at end of file diff --git a/content/ta/fall2017/cpsc220/oct2.md b/content/ta/fall2017/cpsc220/oct2.md new file mode 100644 index 0000000..73581c8 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct2.md @@ -0,0 +1,160 @@ +# Lecture Notes Oct 2nd + +## Array + +`array` is not a reserved word, it's a concept. Arrays are able to hold multiple values under one name of the same type. + +For instance, you can have an array of integers. + +Properties of an array + +- Size (n) +- index [0, n - 1] + +You can declare arrays by saying the type '[]' and the name of the array + +```java +int[] numbers; +double[] gpas; +float[] grades; +``` + +Before you can use the array, you must `new` it + +```java +numbers = new int[10]; +``` + +Where 10 is the size of the array. + +You can combine both the declaration and initialization + +```java +double[] points = new double[7]; +``` + +You can access individual elements of the array by using its index. Indexes start from zero + +```java +points[0] = 5.4; // The first element in the point array is 5.4 +``` + +The `.length` property of an array gives the size of the array + +## For-Loops + Arrays + +You can print out each element in the array using a for loop + +```java +for (int i = 0; i < numbers.length; i++) { + System.out.println(numbers[i]); +} +``` + +You can ask a user to input a value to each element in the array + +```java +for (int i = 0; i < points.length; i++) { + System.out.print("Enter a number: "); + points[i] = scnr.nextInt(); +} +``` + +## While-Loops + Arrays + +You can use a while loop to search the array + +```java +int i = 0; +int number = 5; +// While the index is within the array size and the number isn't found +while (i != number.length && number != numbers[i]) { + i++ +} +if (i == numbers.length) { + System.out.println(number + " was not found.") +} else { + System.out.println(number + " was found at index " + i) +} +``` + +If you don't include the `i != number.length` you will obtain an `IndexOutOfBounds` error. + +The example above is called a *Linear Search*. + +Linear searches work on an unsorted and sorted arrays. + + + +## Methods + Arrays + +You can pass an array into a method + +```java +public static void exampleMethod(int[] sample) { + // Do something +} +public static void main(String[] args) { + int[] s = new int[30]; + exampleMethod(s); +} +``` + + + +## Do-While Loops + +For-loops can run 0 or more times. If you want something to execute at least once. Use a do-while loop. + +```java +do { + // Code +} while (condition); +``` + +For example, to search at least once and asking whether the user wants to search again + +```java +// Assume linearSearch and array are defined +char answer; +Scanner input = new Scanner(System.in); +do { + linearSearch(array, input); + System.out.print("Do you want to search again? (Y/N) "); + input.nextLine(); + answer = input.next().charAt(0); +} while( answer != 'N'); +``` + +You can create any type of loop just by using a while loop. + + + +## Example: Finding the Max + +You can find the max of an array using the following method + +```java +double max = arrayName[0]; +for (int i = 1; i < arrayName.length; i++) { + if (max < arrayName[i]) { + max = arrayName[i]; + } +} +System.out.println("The max is " + max); +``` + + + +## Example: Summing up an array + +You can sum the array using the following method + +```java +double sum = 0; +for (int i = 0; i < arrayName.length; i++) { + sum += arrayName[i]; +} +System.out.println("The sum is " + sum); +``` + diff --git a/content/ta/fall2017/cpsc220/oct23.md b/content/ta/fall2017/cpsc220/oct23.md new file mode 100644 index 0000000..682dc5c --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct23.md @@ -0,0 +1,78 @@ +# Lecture for October 23 + +## Two-Dimensional Arrays + +You can think of a two dimensional array as a grid that is organized by rows then columns. + +To declare a two dimensional array do the following + +```java +int[][] grid = new int[5][5]; // Declares a 2D array of 5 rows and 5 columns +``` + +You can have as many dimensions as you want. For graphics a 3-dimensional array would render 3D points. + +It doesn't have to be inherently visual though, you can have the n-dimensional array look at the interaction between n different variables. For example, the relationships to different questions in a survey. + +Strings are essentially a char array with extra methods attached. We can imitate an array of strings with a 2D char array. + +```java +char[][] helloWorld = new char[5][5]; +hello[0][0] = 'h'; +hello[0][1] = 'e'; +hello[0][2] = 'l'; +hello[0][3] = 'l'; +hello[0][4] = 'o'; +hello[1][0] = 'w'; +hello[1][1] = 'o'; +hello[1][2] = 'r'; +hello[1][3] = 'l'; +hello[1][4] = 'd'; + +``` + +## Nested-For Loops + +To access the elements in a 2D array, you need to use a nested for-loop. + +Here is how you print out the hello world example above + +```java +for (int row = 0; row < helloWorld.length; row++) { + for (int col = 0; col < helloWorld[row].length; col++) { + System.out.print(helloWorld[row][col]); + } + System.out.print(" ") +} +``` + +The code above prints out "hello world" + + + +## 2D Arrays in methods + +You can write a get like method in the following way + +```java +public static void get(int[][] array, int row, int col) { + return array[row][col]; +} +``` + +Arrays in Java are pass by reference not pass by value. Meaning that if you change the array within the method then it will change outside the method. + +```java +public static void insert(int[][] array, int row, int col, int numToInsert) { + array[row][col] = numToInsert; +} +``` + +To make it not be able to change the array inside the method, use the keyword `const` inside the method header. To code below will throw a compiler error. + +```java +public static void insert(const int[][] array, int row, int col, int numToInsert) { + array[row][col] = numToInsert; // This line will throw an errror +} +``` + diff --git a/content/ta/fall2017/cpsc220/oct25.md b/content/ta/fall2017/cpsc220/oct25.md new file mode 100644 index 0000000..fcfc7e7 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct25.md @@ -0,0 +1,21 @@ +# Lecture on Oct 25 + +## 2 Dimension Array of Objects + +You can not only do a two dimensional array of primitive types, but you can also do two dimensional arrays of objects/classes. + +```java +animalLocation[][] map; +map = new animalLocation[5][4]; +``` + +Since we are dealing with classes, you cannot use this array right away. The code above creates the space in memory to store the objects. To have the animalLocation objects in the array, you must `new` each instance of the object. + +```java +for (int i = 0; i < map.length; i++) { + for (int j = 0; j < map[i].length; j++) { + map[i][j] = new animalLocation(); + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/oct30.md b/content/ta/fall2017/cpsc220/oct30.md new file mode 100644 index 0000000..39e4f00 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct30.md @@ -0,0 +1,101 @@ +# Oct 30 Lecture + +## Sorting + +### Bubble Sort + +These instructions are to sort in descending order, to sort in ascending order just negate the condition. + +This sort is a series of iterations, for each iteration you go to the bottom of the array. Then compare if the value is greater than the element before it. If it is, then you + +1. Go to the bottom of the array +2. Compare the value to the one before it + 1. If it's greater than the element before it -> swap +3. Move on to the value before it and repeat step 2. + +Once you go through an iteration, the last thing being compared is the greatest value of the entire array. That means you don't have to check it every time anymore. + +Keep going through all the iterations until n, where n is the size of the array, iterations have been completed. + +### Swapping Values + +If you try to swap variables by saying + +```java +y = x; +x = y; +``` + +then you'll end up overwriting y's value with x and both variable would have x's value. + +If you want to actually swap variables, you must create a temporary variable that saves y's value so that it can be properly assigned to x. + +```java +int temp; +temp = y; +y = x; +x = temp; +``` + +### Implementation (Not Complete) + +```java +// Each iteration +for (int j = 0; j < array.length - 1; j++) { + // Each element in the list + for (int i = 0; i < array.length - 1; i++) { + // Is the element greater than the one after it? + if (array[i] > array[i + 1]) { + // Swap + int temp = array[i + 1]; + array[i + 1] = array[i]; + array[i] = temp; + } + } +} +``` + +This here compares each of the values each time. If you remember before, I said that you don't have to compare the topmost each time. + +### Implementation + +To change this, just change the second loop condition + +```java +// Each iteration +for (int j = 0; j < array.length - 1; j++) { + // Each element in the list + for (int i = 0; i < array.length - 1 - i; i++) { // Note this line + // Is the element greater than the one after it? + if (array[i] > array[i + 1]) { + // Swap + int temp = array[i + 1]; + array[i + 1] = array[i]; + array[i] = temp; + } + } +} +``` + +## Compare + +In Java, you can compare numbers, strings, and even your own customized objects. To compare your own customize object, you must write a method called `compare` in your class. + +### To use your compare method in the sorting algorithm + +```java +// Each iteration +for (int j = 0; j < array.length - 1; j++) { + // Each element in the list + for (int i = 0; i < array.length - 1 - i; i++) { + // Is the element greater than the one after it? + if (array[i].compare(array[i + 1])) { // Note this line + // Swap + int temp = array[i + 1]; + array[i + 1] = array[i]; + array[i] = temp; + } + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/oct4.md b/content/ta/fall2017/cpsc220/oct4.md new file mode 100644 index 0000000..5329411 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct4.md @@ -0,0 +1,30 @@ +# Lecture on October 4th + +## Pass by Copy vs Pass by Reference + +### Pass by Copy + +When you pass a primitive type into a method (int, char, double, float, etc), it makes a copy of the value of the variable and brings it into the method + +### Pass by Reference + +When you pass an array into a method (int[], char[], double[], etc[]), it passes in the reference of the variable into the method. In other words, you give the actual array into the method and allows the method to change it. + +### What's the Implication? + +If you change the primitive in a method, it doesn't actually change the value of the variable. + +If you pass in an array and change it in the method, it has been permanently changed outside the method as well. + +### How do I make it so I can't change my array by accident? + +Use the `final`keyword in the method header + +```java +public static void printAll(final int[] array) { + for (int i = 0; i < array.length; i++) { + System.out.println("Number " + (i + 1) + " is " + array[i]) + } +} +``` + diff --git a/content/ta/fall2017/cpsc220/oct9.md b/content/ta/fall2017/cpsc220/oct9.md new file mode 100644 index 0000000..14bee39 --- /dev/null +++ b/content/ta/fall2017/cpsc220/oct9.md @@ -0,0 +1,37 @@ +# Lecture Notes October 9th + +## Arrays (Cont.) + +### Another way of Array Initialization + +```java +String[] names = {"Jennifer", "Noodle", "Fluffy", "Rosie", "Cinnamon", "Brianne", "Oliver"} +``` + +Everything between the `{}` is the initial values in the names array in the order that it is written. + +Recall that arrays are of a fixed size. The `names` array above has 7 elements. + +### What can I do if I want to add something to the names array? + +Do the following steps: + +1. Create an empty array with the same size as the array +2. Take all the contents in the array and store it in a temporary array +3. Set names equal to another array of a bigger size +4. Take all the contents in temp and store it back to the array of choice +5. Add an element to the array by index + +```java +// (1) +String[] temp = new String[7]; +// (2) +temp.clone(names); +// (3) +names = new String[20]; // Now it can hold up to 20 names +// (4) +names.clone(temp); +// (5) +names[7] = "New name!"; +``` + diff --git a/content/ta/fall2017/cpsc220/sept11.md b/content/ta/fall2017/cpsc220/sept11.md new file mode 100644 index 0000000..b1b6b49 --- /dev/null +++ b/content/ta/fall2017/cpsc220/sept11.md @@ -0,0 +1,220 @@ +# CPSC 220 Lecture 4 + +## Practice Problem + +1. Create a class called Car +2. - Create a private variable of int type called year + - Create a private variable of String type called make +3. Create accessor methods for all data members. +4. Create mutator methods for all data methods. + + + +```java +public class car { // begin car + private int year; + private String make; + public int getYear(void) { + return year; + } + public String getMake() { + return make; + } + public void setYear(int y) { + if (y > 1890) { + year = y; + } else { + System.out.println(y + " is not a valid year."); + } + } + public void setMake(String m) { + make = m; + } +} +``` + +Local variables are only existent within the curly braces that it is defined in. + +## If Statements and Boolean Expressions + +Boolean expressions return a boolean + +```java +1 < 4; // 1 is less than 4: TRUE +3 > 5; // 3 is greater than 5: FALSE +5 == 5; // 5 is equal to 5: TRUE +5 != 5; // 5 is not equal to 5: FALSE +1 >= 1; // 1 is greater than or equal to 1: TRUE +5 <= 1; // 5 is less than or equal to 1: FALSE +``` + + If statements only occur if the boolean expression is true, otherwise the `else` block is executed. + +```java +if (true) { + System.out.println("I am always printed"); +} else { + System.out.println("I am never printed"); +} +``` + +You can only have one `else` per `if`. If you have an `if` you don't necessarily need an `else` + +## Local vs Class Variables + +If you have a local variable and the class variable sharing the same name, then the local variable is always used first. + +```java +public class car { // begin car + private int year; + public void setYear(int year) { + year = year; + } +} +``` + +This is a redundant statement, it makes the argument that is passed in equal to itself. + +To avoid this situation, use the keyword `this` to access the class variable + +```java +public class car { + private int year;   + public void setYear(int year) {     + this.year = year; + } +} +``` + +The code above runs as expected. + +Rewriting our class with `this` + +```java +public class car { // begin car + private int year; + private String make; + public int getYear(void) { + return year; + } + public String getMake() { + return make; + } + public void setYear(int year) { + if (y > 1890) { + this.year = year; + } else { + System.out.println(y + " is not a valid year."); + } + } + public void setMake(String make) { + this.make = make; + } +} +``` + +## Unreachable Code + +When the code hits a `return` statement, it stops executing the rest of the code in the method. Also throws an Unreachable Code Error. + +```java +public int add(int x, int y) { + return x + y; + System.out.println("x + y = " + x + y); +} +add(); +System.out.println("Hello"); +``` + +Here the code above will not compile, though assuming the error doesn't exist then it would only print out "Hello" + +## Constructors + +You cannot have a private or protected constructors. + +Constructors are used to initialize your objects. + +You want to have the class variables to the left of the assignment statement. + +```java +public class car { + private int year; + private String make; + car() { + year = 1890; + make = "Ford"; + } + car(int year, String make) { + this.year = year; + this.make = make; + } +} +``` + + + +## Testers + +Testers are useful to check that the class is implemented correctly. Both the tester and the class have to be in the same folder/directory. + +```java +public class carTester { + public static void main(String[] args) { + Car myCar; // Declaration + myCar = new Car(); // Initilization + Car yourCar = new Car(2009, "Hyundai"); // Declaration + Initialization + } +} +``` + + + +## More about classes + +```java +public class Car { + private String name; + private int odometer; + public void setOdometer(int od) { + odometer = od; + } + public void setName(String n) { + this.name = n; + } + public void changeOilRequest(String name, int od) { + if (name == this.name) { + int difference = od - this.odometer; + if (difference > = 3000) { + // You can call other methods in the class + setOdo(od); // Equivalent to "this.setOdo(od);" + this.odometer = od; + System.out.println("Ready for oil change."); + } else { + System.out.println(name + " not ready for oil change.") + } + } // end if + } // end changeOil request +} // end class +``` + +To call public methods outside the class use the variable name to do so. + +```java +public class CarTester { + public static void main(String[] args) { + Car myCar = new Car(); + myCar.setName("Honda") + myCar.changeOilRequest("Honda", 3400); + } +} +``` + +## Math library + +The `ceil` method rounds up while the `floor` method runs down. + +```java +Math.ceil(3.2); // 4 +Math.ceil(4.1); // 4 +``` + diff --git a/content/ta/fall2017/cpsc220/sept20.md b/content/ta/fall2017/cpsc220/sept20.md new file mode 100644 index 0000000..4fea2f2 --- /dev/null +++ b/content/ta/fall2017/cpsc220/sept20.md @@ -0,0 +1,177 @@ +## Counting Loop + +Looking at the following example code + +```java +int i; +for (i = 0; i < 3; i++) { //begin for + System.out.println("i = " + i); //body +} //end for +System.out.println("After loop, i = " + i); +``` + +`i = 0` is the initializing statement + +`i < 3` is the conditional, that is when the loop ends + +`i++` is the increment/decrement + +`i++` is synonymous with `i = i + 1` + +The initialization statement only occurs once at the beginning of the loop. + +### Execution Example + +Let us go through this for loop example + +- Let us set `i = 0` +- Is `i < 3`? Yes execute the body + - The body executes an output of `"i = 0"` +- Now we increment `i ++`, i is now 1 +- Is `i < 3`? Yes, 1 is less than 3. Execute body + - The computer prints out `"i = 1"` +- Increment `i++` i is now 2 +- Is `i < 3`? Yes 2 is less than 3. Execute body + - The computer prints out `"i = 2"` +- Increment `i++`, i is now 3 +- Is `i < 3`? No 3 is not less than 3 + - Don't execute body of loop + +Exit loop. Print `"After loop, i = 3"` + + + +### Condensing Syntax + +You can also do the declaration in the initialization statement + +```java +for (int i = 0; i < 3; i++) { + System.out.println("i = " + i); +} +``` + +This now runs like above without the `"After loop, i = 3"` print. You cannot access the variable `i` outside the for loop since in this example, it belongs to the for loop's scope. + + + +## Logic Expressions + +### And Statements + +With the AND operator `&&` both the left and right side needs to be true for the expression to be true. + +```java +true && true // true +true && false // false +false && true // false +false && false // false +``` + +### Or Statements + +With the OR operator `||` either the left or right side needs to be true for the expression to be true. + +```java +true || true // true +true || false // true +false || true // true +false || false // false +``` + +### Examples + +**Example**: Print out the number `n` if it is between 10 and 20 (inclusive) + +```java +if (n >= 10 && n <= 20) { + System.out.println(n); +} +``` + +**Example**: Print out the `age` if it is not of young adult age. Young adult range is from 18 to 39 (inclusive) + +```java +if (!(age >= 18 && age <= 39)) { + System.out.println(age); +} +``` + +Or you can use De Morgan's Law (for the curious) + +```java +if (age < 18 || age > 39) { + System.out.println(age); +} +``` + + + +## For Loops (Cont.) + +### Backwards counting + +You can use the loop to count backwards + +```java +for (int i = 10; i > -1; i--) { + System.out.println(i); +} +``` + +This prints the following + +```java +10 +9 +8 +7 +6 +5 +4 +3 +2 +0 +``` + +### Rows-Columns + +You can make rows and columns of asterisks + +```java +for (int j = 0; j < someNumber; j++) { // Corresponds to rows + for (int i = 0; i < someNumber2; i++) { // Corresponds to columns + System.out.print("*"); + } + System.out.println(""); // Goes to the next row +} +``` + +If `someNumber` equals `someNumber2`, then we have the same amount of rows as columns. + +Let `someNumber` equal to 2 and `someNumber2` equal to 2 + +Output: + +``` +** +** +``` + +### Right Triangles + +You can make a right triangle of Tilda with the following code + +```java +for (int i = 1; i <= num; i++) { // Corresponds to the row + for (int j = 0; j < i; j++) { // Corresponds to the column and stops at the current row number + System.out.print("~"); + } + System.out.println(""); // Moves to next row +} +``` + + + +##### What are for-loops used for? *Reusing code* + diff --git a/content/ta/fall2017/cpsc220/sept25.md b/content/ta/fall2017/cpsc220/sept25.md new file mode 100644 index 0000000..bd7ffd5 --- /dev/null +++ b/content/ta/fall2017/cpsc220/sept25.md @@ -0,0 +1,97 @@ +# Lecture in CPSC 220 Sept 25 2017 + +## Constants + +Adding the keyword `final` in front of a variable declaration makes the variable constant. Meaning you cannot later change it in the code. + +```java +final int MAX = 10; +``` + +By industry norm, the style of the variable is to have it in all caps. + +You CANNOT do the following + +```java +final int MAX = 10; +MAX = 15; +``` + + + +## Using Libraries + +1. Import the library +2. Find the method that is appropriate +3. Use it + +Example: + +```java +import java.util.Math; +public class MathTest { + public static void main(String[] args) { + double answer = Math.ceil(5.4); + System.out.println(Math.ceil(4.5)); + } +} +``` + +## Typecasting / Type Conversions + +You can only cast a variable if you are casting it to a type that is larger than the one it was previously. The expression Polack used is that you cannot fit into super skinny jeans, but you can fit into bigger pants. + +```java +double dnum; +float fnum; +int inum; +dnum = (double)fnum * (double)inum; +``` + +## Char vs String + +`String`s are initialized in Java with double quotes while `char`s are initialized with single quotes + +```java +char initial = 'j'; +String name = "Jennifer"; +``` + +Characters can be read in as an integer. + + + +## Random Numbers + +1. Import `java.util.Random;` +2. Declare the random number generator +3. Initialize with `new` +4. Use it + + + +```java +import java.util.Random; +public class RandTest { + public static void main(String[] args) { + Random rand; + rand = new Random(); + int number = rand.nextInt(100); // Random generates number between 0-99 + } +} +``` + +How do you generate numbers in a different range? [50, 150] + +```java +rand.nextInt(100); // 0-99 +rand.nextInt(101) // 0 - 100 +rand.nextInt(101) + 50 //50-150 +``` + +In more general terms + +```java +rand.nextInt(end - start + 1) + start +``` + diff --git a/content/ta/fall2017/cpsc220/sept6.md b/content/ta/fall2017/cpsc220/sept6.md new file mode 100644 index 0000000..e59128d --- /dev/null +++ b/content/ta/fall2017/cpsc220/sept6.md @@ -0,0 +1,298 @@ +# CPSC 220 Lecture 3 + +## Variables + +Variable -- Storage of information + +The type cannot change in a variable. + +Examples of types include + +- int +- float +- double +- String +- char +- boolean + +Declaration: `int num;` + +Initialization: `num = 5;` + +Declaration + Initialization: `int num = 5;` + +### Possible Errors + +**You cannot declare a variable multiple times.** + +Undefined variables are when you do not declare a variable before attempting to use it. + +### Casting + +You need to cast if you are attempting to lose data or store a larger memory type into a smaller one. + +double -> float -> int **(casting required)** + +```java +double gpa = 3.2; +int num1 = 10 * (int)gpa // 30 +``` + + + + + +# Operations + +The basic number operations are + +- + +- - +- * +- / +- % *(the remainder)* + +Examples + +```java +0 % 2 // 0 +1 % 2 // 1 +2 % 2 // 0 + +3 % 2 // 1 +4 % 2 // 0 +5 % 2 // 1 + +3 % 5 // 3 +7 % 5 // 2 +``` + +You can test if something is even using modulus % + +```java +// Assuming i was initiliazed to a value earlier +if (i % 2 == 0) { + System.out.println("i is even"); +} else { + System.out.println("i is odd"); +} +``` + + # System input + +Here is sample code using a Scanner as input + +```java +import java.util.Scanner; +public class ScannerExample { + public static void main(String[] args) { + Scanner in; + in = new Scanner(System.in); + + // Grab numerical values + int num = in.nextInt(); + float gpa = in.nextFloat(); + double weight = in.nextDouble(); + + // Grab a single character + in.nextLine() + char initial = in.next().charAt(0); + + // To get the entire line of a string + in.nextLine(); + String name = in.nextLine(); + } +} +``` + +You need to use `in.nextLine()` to grab the carriage return that is left after grabbing a numeric value. + + + +# Classes and Objects + +Classes are a new type that you can have multiple things of. + +These classes are blueprints that are made up of primitives or more basic types. + +First create a Pet.java file (Name of the class must match the name of the file) + +```java +public class Pet { + private String name; + private int years; +} +``` + +You can then use the Pet class in your main program. The terminology here is that you can create instances or objects of the class. + +In PetTester.java + +```java +public class PetTester { + public static void main(String[] args) { + Pet myPet; + myPet = new Pet(); + } +} +``` + +**Both Pet.java and PetTester.java must be in the same directory/folder** + +### Mutators/Accessors + +Since the variables are private we cannot access them in the main program. To work around this, we can write what is called a mutator method. + +```java +public class Pet { + private String name; + private int years; + + // Mutators + public void setName(String n) { + name = n; + } + public void setYears(int y) { + if (y >= 0) { + years = y; + } else { + System.out.println("No one is less than 0 years old.") + } + } +} +``` + +Now let's use these new methods + +```java +public class PetTester { + public static void main(String[] args) { + Pet mypet; + myPet = new Pet(); + myPet.setName("Fred"); + myPet.setAge(20); + } +} +``` + +We need a method that will allow us to access the data type. Let's add accessors to our pet class. + +```java +public class Pet { + private String name; + private int years; + + // Mutators + public void setName(String n) { + name = n; + } + public void setYears(int y) { + if (y >= 0) { + years = y; + } else { + System.out.println("No one is less than 0 years old.") + } + } + + // Accessors + public String getName() { + return name; + } + public int getYears() { + return years; + } +} +``` + +Now let's get some information from the pet object, such as the age. + +```java +public class PetTester { + public static void main(String[] args) { + Pet mypet; + myPet = new Pet(); + myPet.setName("Fred"); + myPet.setYears(20); + + int year = myPet.getYears(); + } +} +``` + + + +### Constructors + +Constructors lets us initialize variables in the class without having to use mutator methods. + +```java +public class Pet { + private String name; + private int years; + + // Default Constructor + public Pet() { + name = ""; + years = 0; + } + // Non-Default Constructor + public Pet(int y, String n) { + name = n; + years = y; + } + + // Mutator Methods + public void setName(String n) { + name = n; + } + public void setYears(int y) { + if (y >= 0) { + years = y; + } else { + System.out.println("No one is less than 0 years old.") + } + } + + // Accessor Methods + public String getName() { + return name; + } + public int getYears() { + return years; + } +} +``` + +Now let us see this in action. + +```java +public class PetTester { + public static void main(String[] args) { + Pet yourPet = new Pet(10, "Fluffy"); + } +} +``` + +You can have as many constructors as you want, but they must be different. + +Example: + +```java +public class Pet { + ... + pet() { + name = ""; + years = 0; + } + pet(int y, String n) { + name = n; + years = y; + } + pet(String n) { + years = 1; + name = n; + } + ... +} +``` + diff --git a/content/ta/spring2018.md b/content/ta/spring2018.md new file mode 100644 index 0000000..e69de29 diff --git a/content/ta/spring2018/cpsc220.md b/content/ta/spring2018/cpsc220.md new file mode 100644 index 0000000..4d7cfc1 --- /dev/null +++ b/content/ta/spring2018/cpsc220.md @@ -0,0 +1,40 @@ + +# CPSC 220 Computer Programming and Problem Solving Spring 2018 + +[Lecture 1 -- January 16](jan16) + +[Lecture 2 -- January 18](jan18) + +[Lecture 3 -- January 23](jan23) + +[Lecture 4 -- January 25](jan25) + +[Lecture 5 -- January 30](jan30) + +[Lecture 6 -- February 1](feb1) + +[Lecture 7 -- February 6](feb6) + +[Lecture 8 -- February 8](feb8) + +[Lecture 9 -- February 13](feb13) + +[Lecture 10 -- February 20](feb20) + +[Lecture 11 -- February 27](feb27) + +[Midterm Review](midtermreview) + +[Lecture 12 -- March 13](mar13) + +[Lecture 13 -- March 20](mar20) + +[Lecture 14 -- March 22](mar22) + +[Lecture 15 -- March 27](mar27) + +[Lecture 16 -- March 29](mar29) + +[Lecture 17 -- April 3](apr3) + + diff --git a/content/ta/spring2018/cpsc220/apr3.md b/content/ta/spring2018/cpsc220/apr3.md new file mode 100644 index 0000000..45ff8c4 --- /dev/null +++ b/content/ta/spring2018/cpsc220/apr3.md @@ -0,0 +1,39 @@ +# Lecture for April 3rd + +## Inheritance + +The *base class*, *super class*, or *parent class* is the initial class that we are working with. Let's say that you want to *extend* the class, or add additional functionality. The class that inherits from the parent class is called the *child class*, *subclass* or *derived class*. + +## Child Class Syntax + +```java +public class Truck extends Car { + // Truck Appropriate Fields + // Necessary methods for truck +} +``` + +This code adds all the methods from Car into the Truck class. You can then add methods that is specific to a Truck into the Truck class. + +A child class has all parent fields and access to all parent methods! + +## Visibility Modifiers + +Recall the words `public` and `private` + +The `public` modifier makes the field/method accessible by any class + +The `private` modifier makes the field/method only accessible within the method itself + +The protected modifier makes the field/method accessible within the same class or any subclasses. + +## Overriding a Method + +You can override a parent class method by declaring a method in the child class with the same... + +- name +- number of paramters +- parameter types + +but this method would have different behavior! + diff --git a/content/ta/spring2018/cpsc220/feb1.md b/content/ta/spring2018/cpsc220/feb1.md new file mode 100644 index 0000000..91da26c --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb1.md @@ -0,0 +1,66 @@ +# Lecture for February 1st + +## Control Structures + +In this class we will talk about three types of control structures + +- Sequential +- Selection +- Repetition + +Sequential is what is most familiar to us. Write the lines from top to bottom and it executes it in that order + +### Selection + +Selection depends on the question of `if`. + +If it is raining, wear boots + +```java +if (raining) { + wearingBoots = true; +} +``` + +If you want something to happen also when it is not true, consider an `if-else` statement + +If the light is off, turn it on. + +Otherwise, turn it on + +```java +if (lightIsOn) { + lightIsOn = false; +} else { + lightIsOn = true; +} +``` + +Sometimes you can have multiple branches depending on a condition. Let us take a stop light as an example + +```java +if (light == "red") { + car.stop() +} else if (light == "yellow") { + car.slow() +} else { + car.go() +} +``` + +## String comparison + +There is a specific method in the `String` class when it comes to checking for string equality + +```java +boolean equals(String s) +``` + +Let us look at an example + +```java +String word = "hello"; +boolean ans = word.equals("hello"); // Returns true +boolean ans2 = word.equals("Hello"); // Returns false +``` + diff --git a/content/ta/spring2018/cpsc220/feb13.md b/content/ta/spring2018/cpsc220/feb13.md new file mode 100644 index 0000000..82c7de0 --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb13.md @@ -0,0 +1,74 @@ +# Lecture for February 13 + +## Loops + +###Why Loops? + +While some check is true, repeat the work. + +While the cookies aren't baked, keep baking + +### Loop Building Process + +1. Identify one test that must be true when the loop is finished +2. Use the **opposite** form of the test +3. Within loop, make *progress* towards completion of the goal. + +### While syntax + +```java +while (expression) { + // Loop body executes if expression is true +} +// Statements execute after expression is false +``` + +### Getting Input (Songs in a Playlist Psuedocode) + +```java +// Ask user about first song +while (user says play next song) { + // play next song + // ask user about next song +} +``` + +### Nested Loops + +You can have loops inside loops + +```java +int outer = 1; +while (outer < 4) { + int inner = 1; + while (inner < 4) { + System.out.println(outer + ":" + inner); + inner++; + } + outer++; +} +``` + +This code does the following + +```reStructuredText +1:1 +1:2 +1:3 +2:1 +2:2 +2:3 +3:1 +3:2 +3:3 +``` + +### Break Down the Problem + +Never write the entire program at once! This makes it incredibly hard to debug. Instead break it into small parts. + +Write one part -> debug until it works + +Write second part -> debug until it works + +This way you know which part of your code failed, instead of having everything fail. \ No newline at end of file diff --git a/content/ta/spring2018/cpsc220/feb20.md b/content/ta/spring2018/cpsc220/feb20.md new file mode 100644 index 0000000..89d3bd3 --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb20.md @@ -0,0 +1,94 @@ +# Lecture for February 20th + +## Reading a File + +You can get input from a file instead of from the terminal + +```java +FileInputStream fileIn = new FileInputStream("myFile.txt"); +// Our familiar Scanner +Scanner scnr = new Scanner(fileIn); +// We can use our usual Scanner methods +String line = scnr.nextLine(); +fileIn.close(); // Remember to close the file when you're finished with it! +``` + +### Reviewing Scanner Methods + +To understand some of the Scanner methods we need to be aware of the "newline" character. This character is equivalent to the `Enter` button on the keyboard. + +`scnr.nextLine()` This get's all the characters in the buffer up to the newline character. + +`scnr.next()` Grabs the characters in the next "token". Tokens are usually separated by any whitespace type character (spaces, enters, tabs, etc.) + +## Writing to a File + +Prints information to a file instead of to the screen + +```java +FileOutputStream fileOut = new FileOutputStream("myOutfile.txt"); +PrintWriter out = new PrintWriter(fileOut); +out.println("Print this as the first line."); +out.flush(); // Pushes the file changes to the file +fileOut.close(); // If you forget this then it won't remember your changes +``` + +## Arrays + +Arrays are containers of fixed size. It contains a fixed number of values of the **same type**. (Ex: 10 integers, 2 strings, 5 booleans) + +Declaration + +```java +int[] array; // This declares an integer array +``` + +Initialization + +```java +array = new int[7]; // This states that this array can hold up to 7 integers +``` + +Storing a value in an array + +- Square bracket notation is used + +```java +int[] array = new int[7]; +array[0] = 5; // Stores 5 into the first slot +``` + +Now let us attempt to retrieve the value + +```java +int temp = array[0]; +System.out.println(temp); // Prints "5" +``` + +### Traversing an Array + +Let's say we have the following array + +```java +int[] numbers = {3, 5, 2, 7, 9}; +``` + +Let's print out each of the values in the array + +```java +for (int i = 0; i < numbers.length; i++) { + System.out.print("value in " + i " is " + numbers[i]); +} +``` + +### Finding the maximum value in an Array + +```java +int highest = numbers[0]; +for (int i = 0; i < numbers.length; i++) { + if (numbers[i] > highest) { + highest = numbers[x]; + } +} +``` + diff --git a/content/ta/spring2018/cpsc220/feb27.md b/content/ta/spring2018/cpsc220/feb27.md new file mode 100644 index 0000000..017f97c --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb27.md @@ -0,0 +1,91 @@ +# Lecture for February 27th + +## Review for midterm + +Chapter 1 -- Code Style, API + +Chapter 2 -- Variables & Assignments, strings + +Chapter 3 -- input & output + +Chapter 4 -- branches (if, if/else, switch) + +Chapter 5 -- loops (while, for), scope + +Chapter 6 -- File Reading and Writing + +## Separated vs Connected Branches + +What is the output of this code? + +```java +String preferredLanguage = "Spanish"; +if (preferredLanguage.equals("Chinese")) { + System.out.println("Ni hao!"); +} +if (preferredLanguage.equals("Spanish")) { + System.out.println("Hola!"); +} +if (preferredLanguage.equals("French")) { + System.out.println("Bonjour!"); +} +if (preferredLanguage.equals("German")) { + System.out.println("Gutentag!") +} else { + System.out.println("Hello!") +} +``` + +The output is + +```reStructuredText +Hola! +Hello! +``` + +This is because each of the if statements are independent from each other. Whether or not the if statement gets check is not affected by the if statements around it. + +Since the preferred language equals Spanish it outputs `Hola!` But since the language is also *not German* it prints out `Hello!` as well. + + + +## Using an Array + +Square brackets notation is used to access elements, array slots can be used as variables + +```java +int[] array = new int[7]; // Creates an integer array of size 7 +array[0] = 5; +``` + + + +## Swapping Elements + +You can swap `x` and `y` in the following way with a *temporary* variable + +```java +int x = 6; +int y = 1; + +int temp = x; + +x = y; +y = temp; +``` + + + +## Two-Dimensional Arrays + +```java +// Creates a 2D array of two rows and three columns +int[][] a = new int[2][3] +``` + +You can access an element of this 2D array using the conventional square bracket notation + +```java +a[0][0] = 5; +``` + diff --git a/content/ta/spring2018/cpsc220/feb6.md b/content/ta/spring2018/cpsc220/feb6.md new file mode 100644 index 0000000..91d2451 --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb6.md @@ -0,0 +1,139 @@ +# Lecture for February 6th + +## If Statements -- Cont. + +Inside the parenthesis of the `if` statement must be a boolean expression. This is an expression that evaluates to either `true` or `false`. We can do more complex boolean expressions through logical operators. + +## Logical Operators + +NOT `!a` this is true when `a` is false + +AND `a && b ` this is true when both operands are true + +OR `a || b` this is true when either a is true OR b is true + +## Truth Tables + +- Show all possible outcomes +- It breaks the expression down into parts + +### Not + +Let's look at the most simplest case. Not. + +| a | !a | +| ----- | ----- | +| true | false | +| false | true | + +### AND + +| a | b | a && b | +| ----- | ----- | ------ | +| true | true | true | +| true | false | false | +| false | true | false | +| false | false | false | + +Notice here that `a && b` is only true when both `a` and `b` are true. + +### OR + +| a | b | a \|\| b | +| ----- | ----- | -------- | +| true | true | true | +| true | false | true | +| false | true | true | +| false | false | false | + +Notice here that `a || b` is only false when both `a` and `b` are false. + +## Precedence (Order of Operations) + +| | | +| --------------------------------- | ------------------- | +| Parenthesis | `()` | +| Logical Not | `!` | +| Arithmetic Operators | `*` `/` `%` `+` `-` | +| Relational Operators | `<` `<=` `>` `>=` | +| Equality and Inequality operators | `==` `!=` | +| Logical AND | `&&` | +| Logical OR | `||` | + + + +## Playing with Truth Tables Example + +### a && !b + +| a | b | !b | a && !b | +| ----- | ----- | ----- | ------- | +| true | true | false | false | +| true | false | true | true | +| false | true | false | false | +| false | false | true | false | + +### !a || b + +| a | b | !a | !a \|\| b | +| ----- | ----- | ----- | --------- | +| true | true | false | true | +| true | false | false | false | +| false | true | true | true | +| false | false | true | true | + +### !(a || b && c) + +| a | b | c | b && c | a \|\| (b && c) | !(a \|\| b && c) | +| ----- | ----- | ----- | ------ | --------------- | ---------------- | +| true | true | true | true | true | false | +| true | true | false | false | true | false | +| true | false | true | false | true | false | +| false | true | true | true | true | false | +| true | true | false | false | true | false | +| true | false | true | false | true | false | +| false | true | true | true | true | false | +| false | false | false | false | false | true | + +### !a || b && c + +| a | b | c | !a | b && c | !a \|\| b && c | +| ----- | ----- | ----- | ----- | ------ | -------------- | +| true | true | true | false | true | true | +| true | true | false | false | false | false | +| true | false | true | false | false | false | +| false | true | true | true | true | true | +| true | false | false | false | false | false | +| false | true | false | true | false | true | +| false | false | true | true | false | true | +| false | false | false | true | false | true | + +## Distributive Property of Logical Operators + +The following statements are equivalent + +`!(a && b)` is equivalent to `!a || !b` + +Notice how when you distribute the `!` you have to flip the operand as well. `&&` becomes `||` + +Same is true for the following example + +`!(a || b)` is equivalent to `!a && !b` + +`!(a || b && c)` is equivalent to `!a && (!b || !c)` + +## Short Circuit Evaluation + +In an `&&` (AND) statement, if the left side is `false`, there is no need to evaluate the right side. Since it's going to be false anyways!! + +```java +false && true; // FALSE no matter what the right side is +``` + +In an `||` (OR) statement, if the left side is `true, there is no need to evaluate the right side. Since it's going to be true by default!! + +```java +true || false; // TRUE no matter what the right side is +``` + +Java takes this shortcut by default for efficiency reasons \ No newline at end of file diff --git a/content/ta/spring2018/cpsc220/feb8.md b/content/ta/spring2018/cpsc220/feb8.md new file mode 100644 index 0000000..e17dda2 --- /dev/null +++ b/content/ta/spring2018/cpsc220/feb8.md @@ -0,0 +1,112 @@ +# Lecture for February 8th + +##Switch Statements + +Another way to perform multiway branching. Comparing a variable and constant values (`String`, `int`, `char`) + +Switch statements cannot be used with `boolean`, `double`, or `float`s + +### Syntax + +```java +switch (variable) { + case value1: + // Do something + break; + case value2: + // Do something else + break; + //... + default: + // If all else fails do this + break; +} +``` + +`case` is a reserved word that means "when our variable in consideration is equal to..." + +If you forget the `break` keyword, then the program will keep doing the work of all the statements until it hits a `break` keyword. + +### Example Switch Syntax + +```java +switch (birthday) { + case 1: + birthstone = "garnet"; + break; + case 2: + birthstone = "amethyst"; + break; + // .... + default: + System.out.println("Not valid"); + break; +} +``` + +## Comparing Strings Relationally + +Comparing strings are based on the ASCII value of characters + +Sorting strings will result in strings being in alphabetical or reverse alphabetical order. The values of the strings are compared character by character from the left with each ASCII value. + +To compare strings use the `compareTo()` method. Here is the format of the call + +```java +str1.compareTo(str2) +``` + +This returns a *negative number* when `str1` is less than `str2` + +This returns `0` when `str1` is equal to `str1` + +This returns a *positive number* when `str1` is greater than `str2` + +### Example + +```java +String a = "apple"; +String b = "banana"; + +int x = a.compareTo(b); // x = -1 + +int y = b.compareTo(a); // y = 1 +``` + +## Ternary Operator + +With a ternary operator, you can shorten statements where a value is determined by an if statement + +```java +String output = ""; +if (movieRating > 4) { + output = "Fan favorite"; +} else { + output = "Alright"; +} +``` + +Is equivalent to + +```java +String output = ""; +output = (movieRating > 4)? "Fan favorite": "Alright"; +``` + +### Another Example + +```java +double shipping; +if (isPrimeMember) { + shipping = 0; +} else { + shipping = 3.99; +} +``` + +Is equivalent to + +```java +double shipping = (isPrimeMember)? 0: 3.99; +``` + diff --git a/content/ta/spring2018/cpsc220/jan16.md b/content/ta/spring2018/cpsc220/jan16.md new file mode 100644 index 0000000..363cf71 --- /dev/null +++ b/content/ta/spring2018/cpsc220/jan16.md @@ -0,0 +1,47 @@ +# Lecture for January 16 2018 + +## Comments + +You can use multi-line comments or single line comments to note about a piece of code. This helps you so that you don't forget what was happening in the code + +```java +/* Multi Line Comment +I am multiple lines woo! +*/ + +System.out.println("Hello"); // I am an inline comment +``` + +### Javadocs + +This is a standardized method in Java to describe your functions and classes + +```java +/** + * This is a Javadoc comment. A description of your class should appear here + * @author Brandon + * @version 2018 + */ +public class Example{ + /** Another Javadoc comment. + * A description of your program should go here + */ + public static void main(String[] args) { + + } +} +``` + +## Variables + +Convention in Java is for all of your functions/method names to be lowercase. + +Class names should be title cased, each word is capitalized ex: `IntroExample` + + + +## Java API + +The Java API is publicly accessible and is extremely useful for finding methods in existing classes. + +The API documentation for the `String` class is located here: https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/String.html \ No newline at end of file diff --git a/content/ta/spring2018/cpsc220/jan18.md b/content/ta/spring2018/cpsc220/jan18.md new file mode 100644 index 0000000..3cf89cb --- /dev/null +++ b/content/ta/spring2018/cpsc220/jan18.md @@ -0,0 +1,188 @@ +# Lecture for January 18 + +## Variables and Assignment + +Think about variables as buckets that hold information. Once the bucket is created, only one type of item can go in the bucket. + +```java +sand bucket1; +``` + +We can say that bucket1 is of type `sand`, that means the only thing that can go in the bucket is sand. + +```java +int bucket1; +double bucket2; +``` + +From the two lines above, we have *declared* the variable. + +Variables store state, they are a name for a location in memory. + +Always remember to initialize your variables. Otherwise there's nothing in the bucket! + +```java +bucket1 = 5; +``` + + You can combine both the declaration and initialization + +```java +int count = 15; +``` + +Remember when dealing with variables to stay true with the type, don't mix a bucket of water with a bucket of sand. + +We can update `count` to contain a true value + +```java +count = 55; +``` + +`count` no longer has the value of `15` in it. There's no record of it! It has been overwritten with the value `55` + +### Primitive Types + +There are 8 primitive types in Java + +- boolean +- char +- byte +- short +- int +- long +- float +- double + +byte through double are all *numeric* types + +#### Boolean + +`boolean` can only be equal to `true` or `false` + +```java +boolean student = true; +``` + +#### Char + +Stores a single character from the Unicode set + +There are 16 bits per character which adds up to 65,536 characters + +ASCII is the US subset of the characters. You can look this up online when needing to deal with ASCII values + +```java +char firstLetter = 'A'; +``` + +### Numeric types + +The different numeric types determine the precision of your number. Since numbers are not represented the same in the computer as they are in real life, there are some approximations. + +The default type you can use your code is `int` for integers and `double` for numbers with a decimal point + +There are certain types of operations you can perform on numeric type + +| Symbol | Meaning | Example | Value | +| ------ | --------------- | ---------- | ----- | +| + | addition | 43 + 8 | 51 | +| - | subtraction | 43.0-8.0 | 35.0 | +| * | multiplication | 43 * 8 | 344 | +| / | division | 43.0 / 8.0 | 5.375 | +| % | remainder / mod | 43 % 8 | 3 | +| - | unary minus | -43 | -43 | + +#### Increment/ Decrement + +There are two types of in/decrementers postfix and prefix + +Postfix: + +```java +int x = 0; +int y = 7; +x++; // Shortcut for x = x + 1 +y--; // Shortcut for y = y - 1 +``` + +Prefix + +```java +int x = 0, y = 7, z; +z = y * x++; // Equivalent to (y * x) + 1 = 7 * 0 +z = y * ++x; // Equivalent to y * (x + 1) = 7 * 1 +``` + +### Data Conversion + +There are two types of data conversion, implicit and explicit + +The compiler can perform implicit data conversion automatically. + +Performing an explicit data conversion requires additional work on the programmer's part + +A conversion is implicit if you do **not** lose any information in it + +```java +double price = 6.99; +int sale = 3; +double total = price - sale; +``` + +A *cast* is an explicit data conversion. This is requested by a programmer, this can lead to loss of information + +```java +int nextChar = 'b'; +Character.isAlphabetic( (char) nextChar); // Let's you print the actual letter 'b' instead of the number corresponding to it + +float price = 6.99; +int cost = (int) price; // cost is now 6 +``` + +### Printing variables + +You can print the values of variables using `System.out.println` and `System.out.print` + +The difference is that `System.out.println` adds a new line at the end. Meaning the next print out will be on the next line. + +```java +int cost = 5; +double sale = .30; +System.out.print(cost); +System.out.print(sale); +// Prints out '5.30` +System.out.println(cost); +System.out.println(sale); +// Prints out '5' +// Prints out '0.30' +``` + +To add a space between two variables in a print, add `" "` to the expression in between the two variables + +```java +System.out.println("The total cost is " + 5 " dollars and" + " " + 93 + " cents"); +// The total cost is 5 dollars and 94 cents +``` + +### Input from User + +You can get import from the user, we can do this using the `Scanner` class. + +First import it at the top of your file + +```java +import java.util.Scanner; +``` + +All you can do with `Scanner` is outlined in the Java API at this link https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Scanner.html + +Create a Scanner object + +```java +Scanner input = new Scanner(System.in); +System.out.print("Please enter an integer: "); +price = input.nextInt(); // The integer that the user inputs is now stored in price +System.out.println("Your input: " + price); +``` + diff --git a/content/ta/spring2018/cpsc220/jan23.md b/content/ta/spring2018/cpsc220/jan23.md new file mode 100644 index 0000000..d18f20d --- /dev/null +++ b/content/ta/spring2018/cpsc220/jan23.md @@ -0,0 +1,92 @@ +# Lecture for January 23 + +## Java Class + +In Java, your code must live in a class. + +```java +public class NameOfClass { + public static void main(String[] args) { + // All program code + } +} +``` + +It is important that `NameOfClass` is named meaningfully for the code. It is convention to use CamelCase when using classes. (Capitalize your class names!) + +All methods have a method signature, it is unique to it. For main it is the words `public static void` and the argument `String[] args`. + +`public` means that any other piece of code can reference it. + +`void` means that the method returns nothing + +`main` is the name of the method. It is important to have `main` since that tells the Java Interpreter where to start in your program. + +`String[] args` is the command line arguments inputted into the program. For this part of the class, we don't need to worry about it. + +If you noticed `String` is a class, it is not a primitive type. This is denoted in Java by having it capitalized. + +## Arithmetic Expressions + +There is an order of operations in programming as well. It goes like this: + +1. Parenthesis +2. Unary Operations +3. *, /, % +4. +, - + +And from there you read from left to right. + +## Constant Variables + +These are variables that can never be changed + +```java +final int MINUTES_PER_HOUR = 60 +``` + +The keyword `final` indicates to the Java compiler that it is a constant variable. + +By convention, constants are in all caps with underscores being separated between the words + + + +## Java Math Library + +There are some arithmetic expressions that we want to be able to do and we cannot achieve that simply with the standard operations + +| Method | Description | +| -------------- | ----------------------------- | +| Math.sqrt(x) | square root | +| Math.abs(x) | absolute value | +| Math.pow(a, b) | exponentiation $a^b$ | +| Math.max(a, b) | returns the maximum of a or b | +| Math.min(a, b) | returns the minimum of a or b | +| Math.round(x) | rounds to the nearest integer | + +## Example: Finding Areas + +```java +public class MoreVariables + public static void main(String[] args) { + // Decrate a variable + int x; + + // Initialize ia variable + x = 5; + + // Area of a square + int squareArea = x * x; + System.out.println("Area of a square: " + squareArea); + double newSquare = Math.pow(x, 2); + System.out.println("Area of square: " + newSquare); + + // Area of Circle + final double PI = 3.14159; + double radius = 3; + double circleArea = radius * radius * PI; + System.out.println("Area of circle: " + circleArea); + +} +``` + diff --git a/content/ta/spring2018/cpsc220/jan25.md b/content/ta/spring2018/cpsc220/jan25.md new file mode 100644 index 0000000..949c5c4 --- /dev/null +++ b/content/ta/spring2018/cpsc220/jan25.md @@ -0,0 +1,137 @@ +# Lecture for January 25 + +## Strings + +These are concatenated chars + +```java +'d' + 'o' + 'g' // equivalent to "dog" +``` + +```java +"straw" + "berry" // strawberry +``` + +Strings are denoted by double quotes `""` rather than a string which is denoted by single quotes `''` + +String is not a primitive type, it is a class. Hence, why it is capitalized in Java. + +The `java.lang.String` is automatically imported in Java. + +To declare and initialize a String + +```java +String name = "Henry"; +``` + +In memory it appears as + +| H | 'e' | 'n' | 'r' | 'y' | +| ---- | ---- | ---- | ---- | ---- | +| | | | | | + +### String Methods + +```java +int length() +``` + +```java +boolean equals(String another) +``` + +```java +boolean startsWith(String prefix) +``` + +```java +boolean endsWith(String suffix) +``` + +```java +String substring(int start, int end) +``` + +```java +int indexOf(int ch) +``` + +```java +String toLowerCase() +``` + +### Using String Methods + +```java +char first = name.charAt(0); +``` + +Remember in Java, that it starts counting from zero! If you try to access a letter that doesn't exist, it will produce an `IndexOutOfBounds` error. + +## Errors + +There are two types of errors, compile-type errors and run-time errors. Later we will talk about debugging skills such as making "breakpoints" in your code so you can analyze the different variable values. + +### Compile Time Errors + +Compile time errors are generated due to syntax errors. Forgot a semicolon? Missing a brace? + +### Run-time Errors + +These are logic errors. Not derived from syntax errors. An example of one that was discussed earlier is the `IndexOutOfBounds` error. + + + +## Tricky Thing About Input + +Let's talk about input right now. Let's say you have the following scenario + +```java +Scanner input = new Scanner(System.in); +System.out.println("Enter pet's age: "); +int age = input.nextInt(); +System.out.println("Enter pet's name: "); +String name = input.nextLine(); +System.out.println("Enter pet's breed: "); +String breed = input.next(); +``` + +Then when we start to run the program... + +```reStructuredText +Enter pet's age: +14 +Enter pet's name: +Enter pet's breed: +Labradoodle +``` + +Why did it skip pet's name? Let's run through the process again + +```reStructuredText +Enter pet's age: +14 [ENTER] +Enter pet's name: +Enter pet's breed: +Labradoodle +``` + +Here the [ENTER] key gets saved into name. + +To resolve this, just use an `input.nextLine()` to throw away that [ENTER] + +```java +Scanner input = new Scanner(System.in); +System.out.println("Enter pet's age: "); +int age = input.nextInt(); +System.out.println("Enter pet's name: "); +input.nextLine(); +String name = input.nextLine(); +System.out.println("Enter pet's breed: "); +String breed = input.next(); +``` + + + + + diff --git a/content/ta/spring2018/cpsc220/jan30.md b/content/ta/spring2018/cpsc220/jan30.md new file mode 100644 index 0000000..e5e8095 --- /dev/null +++ b/content/ta/spring2018/cpsc220/jan30.md @@ -0,0 +1,91 @@ +# Lecture for January 30 + +## Random Number Generator + +One of the ways you can do a random number generator is through this method: + +Import a class called random + +```java +import java.util.Random; +``` + +Then you need to create a `Random` object + +```java +Random rand = new Random(); +``` + +After this you can call the `nextInt()` method to get a random number between 0 and $2^{32}$ + +```java +int randInt = rand.nextInt(); +``` + +If you don't want a random number between 0 and $2^{32}$ but instead to another maximum value, then you can call the `nextInt` method inserting the max integer as a parameter. + +Random Integer from 0-10 (not including 10) + +```java +int randInt2 = rand.nextInt(10); +``` + +## Output + +We have already encountered `System.out.println` and `System.out.print` but let us go over the differences again. + +`System.out.println()` prints the contents inside the parenthesis and appends a newline character afterwards so that the next output is on a new line + +`System.out.print()` prints the contents inside the parenthesis and does not output a newline character + + + +### Formatting Output + +If you want more control on how your output is displayed, it is recommended that you use `System.out.printf` to format your output + +First, you need to specify your type using the % instruction + +- d for integer +- f for decimal + +Example: + +```java +int sum = 50; +System.out.printf("Total = %d", sum); +``` + +This outputs + +```reS +Total = 50 +``` + +Notice here that there is no concatenation required like the previous two methods, instead you insert the variables as parameters + +Let us deconstruct the % instruction + +% __ __ . __ __ + +The first underline is the + - 0 space (sometimes we want to pad the money with zeros) + +The second underline is the width of the text + +The third underline is the number of decimal places + +The the final underline is the specifier `f` for decimal and `d` for integer + +Example + +```java +double amount = 0.5; +System.out.printf("Total Due: %0.2f") +``` + +This outputs + +```reStructuredText +Total Due: 0.50 +``` + diff --git a/content/ta/spring2018/cpsc220/mar13.md b/content/ta/spring2018/cpsc220/mar13.md new file mode 100644 index 0000000..5bac319 --- /dev/null +++ b/content/ta/spring2018/cpsc220/mar13.md @@ -0,0 +1,78 @@ +# Lecture for March 13th + +## Methods + +Methods are small blocks of statements that make it easier to solve a problem. It usually focuses on solving a small part of the overall problem. + +Usually in methods you provide some sort of input and get some output out of it. + +### Advantages + +- Code readability +- Modular program development (break up the problem in chunks) +- Incremental development +- No redundant code! + +### Method definition + +Consists of a method name, input and output and the block of statements. + +Usually this is succinctly written using JavaDocs which is what you see in the JavaAPI + +### Method Call + +A method call is the execution of the method. The statements defined in the method is what will execute. + +### Method Stubs + +Recall from method definition the parts of the method definition. Now look at the following method + +```java +String[] split(String s) +``` + +The output here is `String[]` + +The method name is `split` + +The input is `String s` + +## Modular Programming + +Let us look at the following example: + +The program should have a list of grocery prices. It should be able to calculate the total cost of groceries. The store gives a student discount of 5%. The program should calculate this discount and update the total, it should calculate and add the 2.5% tax. + +- First you should add it all up +- Then compute the discount +- Then add the tax + +## Parts of a method definition + +```java +public static int timesTwo(int num) { + int two = num * 2; + return two; +} +``` + +It first starts off by declaring the visibility `public` + +The return type if `int` + +The method name is `timesTwo` + +The input parameter is `int num` + +Between the curly braces is the *body* of the method + +## Calling a Method + +```java +int a = 5; +int b = 3; + +int ans = multiply(a, b) +``` + +The method call is `multiply(a, b)` and the result is stored in the variable `ans` \ No newline at end of file diff --git a/content/ta/spring2018/cpsc220/mar20.md b/content/ta/spring2018/cpsc220/mar20.md new file mode 100644 index 0000000..2210478 --- /dev/null +++ b/content/ta/spring2018/cpsc220/mar20.md @@ -0,0 +1,32 @@ +# Lecture for March 20th + +## Unit Testing + +With unit testing you are able to test small parts as you go. With unit testing, you can test many examples and border cases (extreme inputs) to see how your code reacts to different input. + +## Variable Scope + +A variable declared inside a method is only accessible inside that method. + +A good rule of thumb is that if a variable is declared within curly braces {} then it does not exist outside that curly brace. + +## Method Overloading + +Sometimes we need to have methods with the same name but different input parameters. + +```java +public static int multiply(int a, int b) { + return a * b; +} +``` + +This method only works with integers, what if we want to multiply two doubles? + +We can overload the method by declaring another method with the same name. + +```java +public static double multiply(double a, double b) { + return a * b; +} +``` + diff --git a/content/ta/spring2018/cpsc220/mar22.md b/content/ta/spring2018/cpsc220/mar22.md new file mode 100644 index 0000000..c560df9 --- /dev/null +++ b/content/ta/spring2018/cpsc220/mar22.md @@ -0,0 +1,72 @@ +# Lecture on March 22nd + +## Method Documentation + +Java has a special way that you can document your methods such that it will create documentation for you if you follow the convention. + +The Java API actually uses this technique to produce its own documentation. + +To create this, indicate a method with special comments that begin with `/**` and ends with `*/` + +It contains *block tags* that describe input and output parameters + +`@param` and `@return` + +### Example + +```java +/** + * @param y an integer to sum + * @param x an integer to sum + * @return the sum of x and y + */ +public int multiply(int x, int y) { + return x + y; +} +``` + +## Passing a Scanner + +We only want to create one **user input scanner** per program, we also only want one **file input scanner** per program. + +If a method needs a scanner, you can pass the one you already created in as an input parameter. + +## Array as Input Parameter + +Primitive types (`int`, `char`, `double`, etc.) are passed by value. Modifications made inside a method cannot be seen outside the method. + +Arrays on the other hand, is pass by reference. Changes made to an array inside the method can be seen outside the method. + +```java +public static void main(String[] args) { + int[] nums = {1, 3, 5, 7, 9}; + + timesTwo(nums); +} +public static void timesTwo(int[] arr) { + for (int i = 0; i < arr.length; i++) { + arr[i] *= 2; + } +} +``` + +At the end of the `timesTwo` method call, the variable `nums` would have `{2, 6, 10, 14, 18}` + +## Sizes of Arrays + +### Perfect Size Arrays + +When we declare an array, Java automatically fills every slot of the array with the type in memory. So if you know that you need exactly 8 slots, then you only ask for 8. + +### Oversize Arrays + +This is when we don't know how many slots we need. Therefore, we ask for more than we think we'll need. That way we don't go out of bounds. + +If we do this, then we don't know how many elements we have already inserted into the array. Since the length is the number of slots. + +So we can create another variable, which will keep track of the index in where we can add the next element. + +We use oversized arrays when the size of the array is unknown or may change. + + + diff --git a/content/ta/spring2018/cpsc220/mar27.md b/content/ta/spring2018/cpsc220/mar27.md new file mode 100644 index 0000000..50eac71 --- /dev/null +++ b/content/ta/spring2018/cpsc220/mar27.md @@ -0,0 +1,140 @@ +# Lecture for March 27 + +## In the Real World... + +Objects are known for having characteristics. A car has on average 4 wheels, 2-4 doors, a steering wheel. + +Objects can perform actions. A car can drive, hold cargo, and honk. + +## In the Programming World... + +Object-Oriented Programming + +- Focuses on objects +- Are not linear +- Adds organization to a program +- Fits with human cognition (making abstractions) + +## Class Structure + +```java +public class Classname { + // Fields + // Constructors + // Methods +} +``` + +## Fields + +Fields are instance variables, they store values, help define state, and exist in memory for the lifetime of the object. + +```java +public class Car { + private double price; + private double gas; +} +``` + +## Constructor + +We can build an object through a constructor. It is a special kind of method, this method requires that you not have a return type and that you name it the same as the class itself. + +Constructors help set default field values for the different properties of our class. + +```java +public class Car { + // Begin Constructor + public Car(double cost) { + this.price = cost; + this.gas = 0; + } + // End Constructor + private double price; + private double gas; +} +``` + +**Note:** The `this` keyword refers to the object's fields. This helps keep it separate from other variables you can create in the method and the input parameters you receive. + +## Accessor Method - "Getter" + +We like to classify methods into two types, accessors and mutators. + +Getter methods return a copy of an instance field. It does not change the state of the object. + +```java +public double getPrice() { + return this.price; +} +``` + +## Mutator Method - "Setter" + +This type of method modifies an instance field. It does not return anything and changes the state of the object. + +```java +public void setPrice(double cost) { + this.price = cost; +} +``` + +## Example of Car Class In All Its Glory + +```java +public class Car { + // Instance Variables + private int mpg; + private double price; + + // Constructors + public Car() { + this.price = 0; + this.mpg = 0; + } + public Car(double cost, int mpg) { + this.price = cost; + this.mpg = mpg; + } + + // Accessors + public double getPrice() { + return this.price'' + } + public int getMpg() { + return this.mpg; + } + + // Mutators + public void setPrice(double cost) { + this.price = cost; + } + public void setMpg(int mpg) { + this.mpg = mpg; + } +} +``` + +## Using Classes + +Just like how we used the `Scanner` class, we can also use our new `Car` class. + +```java +public class TestCar { + public static void main(String[] args) { + // Declare an object reference + Car c; + + // Initialize the object + c = new Car(); + + // Update the fields of the object + c.setPrice(3000); + c.setMpg(22); + + // Print object information + System.out.println("Price is " + c.getPrice() ) + } +} +``` + diff --git a/content/ta/spring2018/cpsc220/mar29.md b/content/ta/spring2018/cpsc220/mar29.md new file mode 100644 index 0000000..c5a51e4 --- /dev/null +++ b/content/ta/spring2018/cpsc220/mar29.md @@ -0,0 +1,67 @@ +# Lecture for March 29th + +## Enumerated Types + +These represent a fixed set of constants and include all possible values within them. + +Let's look at coins. On a daily basis in the US, we use the following coins: + +- Penny +- Nickel +- Dime +- Quarter + +Other examples include the days of the week, clothes sizes, etc. + +## Enum Syntax + +Let's define an `enum` type + +```java +public enum Coin { PENNY, NICKEL, DIME, QUARTER} +``` + +Now declare and initialize a variable + +```java +Coin myCoin = Coin.PENNY +``` + +## Arrays vs ArrayList + +Arrays require you to say upfront, how many slots you need. ArrayLists are more flexible since you can change the length of the array during Runtime. + +Arrays can store objects and primitives such as `int`, `char`, `boolean`, etc. + +ArrayLists can only store objects. + +### How to declare an ArrayList + +```java +ArrayList list = new ArrayList(); +``` + +### Differences between getting the length of the array + +**Array** + +```java +int length = array.length; +``` + +**ArrayList** + +```java +int length = array.size(); +``` + +## For Each Loop + +This is a special loop in where you tell it to go through all the elements of the array, without specifying an index. + +```java +for (String b : buildings) { + System.out.print(b); +} +``` + diff --git a/content/ta/spring2018/cpsc220/midtermreview.md b/content/ta/spring2018/cpsc220/midtermreview.md new file mode 100644 index 0000000..1258854 --- /dev/null +++ b/content/ta/spring2018/cpsc220/midtermreview.md @@ -0,0 +1,45 @@ +# More Midterm Review + +Let us suppose that we have the following array + +```java +int[] b = {11, 12, 15, 16, 21} +``` + +## Increase all elements by 2 + +```java +for (int i = 0; i < b.length; i++) { + b[i] += 2; +} +``` + +## Print all elements of array + +```java +for (int i = 0; i < b.length; i++) { + System.out.println(b[i]); +} +``` + +## Sum all the elements of an array + +```java +int sum = 0; +for (int i = 0; i < b.length; i++) { + sum += b[i]; +} +``` + +## Access Last Element of Array + +```java +System.out.println(b[b.length - 1]); +``` + +## Access the middle element + +```java +System.out.println(b[b.length / 2]); +``` + diff --git a/content/ta/summer2017.md b/content/ta/summer2017.md new file mode 100644 index 0000000..e69de29 diff --git a/content/ta/summer2017/cpsc110.md b/content/ta/summer2017/cpsc110.md new file mode 100644 index 0000000..6912fc9 --- /dev/null +++ b/content/ta/summer2017/cpsc110.md @@ -0,0 +1,13 @@ +# CPSC 110 Introduction to Computer Science Summer 2017 + +For the summer session, I didn't write in depth lecture notes. Instead I wrote short complementary blog posts help out with the labs. + +[Viewing Java Applets](/blog/2017-05-24-viewing-java-applets/) + +[Using System Themes in Java Swing](/blog/2017-06-05-using-system-themes-java-swing/) + +[Java Swing Components](/blog/2017-06-05-java-swing-components/) + +[Escape Sequences in Java](/blog/2017-08-28-escape-sequences-java/) + +[Obtaining Command Line Input in Java](/blog/2017-08-28-obtaining-command-line-input-java/) diff --git a/content/transcript.md b/content/transcript.md new file mode 100644 index 0000000..d14ede8 --- /dev/null +++ b/content/transcript.md @@ -0,0 +1,136 @@ +--- +Title: Transcript +Description: Page listing the courses I've taken +--- + +# Transcript + +Below is a list of courses I've taken in the past for credit. + +## Spring 2019 + +Deep Reinforcement Learning (CPSC 491) + +Real Analysis I (MATH 471) + +Abstract Algebra I (MATH 431) + +Operating Systems (CPSC 405) + +Digital Storytelling (CPSC 106) + +## Fall 2018 + +Reinforcement Learning (CPSC 491) + +Programming Languages (CPSC 491) + +Competitive Programming (CPSC 491) + +Multivariate Statistics (STAT 461) + +Foundations of Advance Mathematics (MATH 330) + +Applications of Databases (CPSC 350) + +## Spring 2018 + +Foundations for Data Science (Data 219) + +Theory of Computation (CPSC 326) + +Data Structures and Algorithms (CPSC 340) + +Differential Equations (MATH 312) + +Cluster Analysis (STAT 491) + +## Fall 2017 + +Computer Systems and Architecture (CPSC 305) + +Introduction to Data Science (DATA 101) + +Linear Algebra (MATH 300) + +Methods in Mathematical Physics (PHYS 317) + +Probability & Statistical Inference I (STAT 381) + +Undergraduate Research in Physics (URES 197J) + +## Fall 2017 + +Computer Systems and Architecture (CPSC 305) + +Introduction to Data Science (DATA 101) + +Linear Algebra (MATH 300) + +Methods in Mathematical Physics (PHYS 317) + +Probability & Statistical Inference I (STAT 381) + +Undergraduate Research in Physics (URES 197J) + +## Fall 2017 + +Computer Systems and Architecture (CPSC 305) + +Introduction to Data Science (DATA 101) + +Linear Algebra (MATH 300) + +Methods in Mathematical Physics (PHYS 317) + +Probability & Statistical Inference I (STAT 381) + +Undergraduate Research in Physics (URES 197J) + +## Spring 2017 + +Intro to Discrete Mathematics (CPSC 125A) + +Object-Oriented Analysis & Design (CPSC 240) + +Statistical Methods (MATH 280) + +University Physics II, with Lab (PHYS 106) + +Undergraduate Research in Physics (URES 197J) + +## Fall 2016 + +Software Development Tools (CPSC 225) + +Numbers Rule Your World (FSEM 100M1) + +Intro to Statistics (MATH 200) + +American Music (MUHL 156) + +University Physics I, with Lab (PHYS 105) + +## Advance Placement + +Computer Programming and Problem Solving (CPSC 220) + +Intro to Human Geography (GEOG 102) + +American History to 1865 (HIST 131) + +American History since 1865 (HIST 132) + +Calculus I (MATH 121) + +Calculus II (MATH 122) + +Calculus III (MATH 223) + +General Psychology (PSYCH 100) + + + + + + diff --git a/static/files/courses/BayesianStatistics/Challenger.png b/static/files/courses/BayesianStatistics/Challenger.png new file mode 100644 index 0000000..82d53b2 Binary files /dev/null and b/static/files/courses/BayesianStatistics/Challenger.png differ diff --git a/static/files/courses/BayesianStatistics/challengerfitted.png b/static/files/courses/BayesianStatistics/challengerfitted.png new file mode 100644 index 0000000..38e32c7 Binary files /dev/null and b/static/files/courses/BayesianStatistics/challengerfitted.png differ diff --git a/static/files/courses/BayesianStatistics/heightpairs.png b/static/files/courses/BayesianStatistics/heightpairs.png new file mode 100644 index 0000000..41de2e2 Binary files /dev/null and b/static/files/courses/BayesianStatistics/heightpairs.png differ diff --git a/static/files/groupssimplified.pdf b/static/files/groupssimplified.pdf new file mode 100644 index 0000000..0830c19 Binary files /dev/null and b/static/files/groupssimplified.pdf differ diff --git a/static/files/images/0932485094325.png b/static/files/images/0932485094325.png new file mode 100644 index 0000000..e411cfe Binary files /dev/null and b/static/files/images/0932485094325.png differ diff --git a/static/files/images/1573183066061.png b/static/files/images/1573183066061.png new file mode 100644 index 0000000..46361d1 Binary files /dev/null and b/static/files/images/1573183066061.png differ diff --git a/static/files/images/1578623897330.png b/static/files/images/1578623897330.png new file mode 100644 index 0000000..75937ea Binary files /dev/null and b/static/files/images/1578623897330.png differ diff --git a/static/files/images/1578887790276.png b/static/files/images/1578887790276.png new file mode 100644 index 0000000..8805817 Binary files /dev/null and b/static/files/images/1578887790276.png differ diff --git a/static/files/research/ClusterAnalysisSpring2018.html b/static/files/research/ClusterAnalysisSpring2018.html new file mode 100644 index 0000000..c6b6226 --- /dev/null +++ b/static/files/research/ClusterAnalysisSpring2018.html @@ -0,0 +1,222 @@ + + + + +ClusterAnalysisSpring2018.md + + +

Cluster Analysis Spring 2018

Distance, Dimensionality Reduction, and Tendency

  • Distance

    • Euclidean Distance
    • Squared Euclidean Distance
    • Manhattan Distance
    • Maximum Distance
    • Mahalanobis Distance
  • Which distance function should you use?

  • PCA

  • Cluster Tendency

    • Hopkins Statistic
  • Scaling Data

Validating Clustering Models

  • Clustering Validation
  • Cross Validation

Connectivity Models

  • Agglomerative Clustering

    • Single Linkage Clustering
    • Complete Linkage Clustering
    • Unweighted Pair Group Method with Arithmetic Mean (If time permits)
  • Dendrograms

  • Divisive Clustering

  • CURE (Clustering using REpresentatives) algorithm (If time permits)

Cluster Evaluation

  • Internal Evaluation

    • Dunn Index
    • Silhouette Coefficient
    • Davies-Bouldin Index (If time permits)
  • External Evaluation

    • Rand Measure
    • Jaccard Index
    • Dice Index
    • Confusion Matrix
    • F Measure (If time permits)
    • Fowlkes-Mallows Index (If time permits)

Centroid Models

  • Jenks Natural Breaks Optimization
  • Voronoi Diagram
  • K means clustering
  • K medoids clustering
  • K Medians/Modes clustering
  • When to use K means as opposed to K medoids or K Medians?
  • How many clusters should you use?
  • Lloyd's Algorithm for Approximating K-means (If time permits)

Density Models

  • DBSCAN Density Based Clustering Algorithm
  • OPTICS Ordering Points To Identify the Clustering Structure
  • DeLi-Clu Density Link Clustering (If time permits)
  • What should be your density threshold?

Analysis of Model Appropriateness

  • When do we use each of the models above?

Distribution Models (If time permits)

  • Fuzzy Clusters
  • EM (Expectation Maximization) Clustering
  • Maximum Likelihood Gaussian
  • Probabilistic Hierarchal Clustering

Textbooks

Cluster Analysis 5th Edition

Cluster Analysis: 2014 Edition (Statistical Associates Blue Book Series 24)

Schedule

In an ideal world, the topics below I estimated being a certain time period for learning them. Of course you have more experience when it comes to how long it actually takes to learn these topics, so I'll leave this mostly to your discretion.

Distance, Dimensionality Reduction, and Tendency -- 3 Weeks

Validating Cluster Models -- 1 Week

Connectivity Models -- 2 Weeks

Cluster Evaluation -- 1 Week

Centroid Models -- 3 Weeks

Density Models -- 3 Weeks

Analysis of Model Appropriateness -- 1 Week

The schedule above accounts for 14 weeks, so there is a week that is free as a buffer.

Conclusion

Creating this document got me really excited for this independent study. Feel free to give me feedback :)

+ + \ No newline at end of file diff --git a/static/files/research/ClusterAnalysisSpring2018.md b/static/files/research/ClusterAnalysisSpring2018.md new file mode 100644 index 0000000..002dc8a --- /dev/null +++ b/static/files/research/ClusterAnalysisSpring2018.md @@ -0,0 +1,119 @@ +# Cluster Analysis Spring 2018 + +### Distance, Dimensionality Reduction, and Tendency + +- Distance + - Euclidean Distance + - Squared Euclidean Distance + - Manhattan Distance + - Maximum Distance + - Mahalanobis Distance +- Which distance function should you use? +- PCA +- Cluster Tendency + - Hopkins Statistic +- Scaling Data + +### Validating Clustering Models + +- Clustering Validation +- Cross Validation + +### Connectivity Models + +- Agglomerative Clustering + - Single Linkage Clustering + - Complete Linkage Clustering + - Unweighted Pair Group Method with Arithmetic Mean (If time permits) +- Dendrograms +- Divisive Clustering +- CURE (Clustering using REpresentatives) algorithm (If time permits) + +### Cluster Evaluation + +- Internal Evaluation + - Dunn Index + - Silhouette Coefficient + - Davies-Bouldin Index (If time permits) +- External Evaluation + - Rand Measure + - Jaccard Index + - Dice Index + - Confusion Matrix + - F Measure (If time permits) + - Fowlkes-Mallows Index (If time permits) + +### Centroid Models + +- Jenks Natural Breaks Optimization +- Voronoi Diagram +- K means clustering +- K medoids clustering +- K Medians/Modes clustering +- When to use K means as opposed to K medoids or K Medians? +- How many clusters should you use? +- Lloyd's Algorithm for Approximating K-means (If time permits) + +### Density Models + +- DBSCAN Density Based Clustering Algorithm +- OPTICS Ordering Points To Identify the Clustering Structure +- DeLi-Clu Density Link Clustering (If time permits) +- What should be your density threshold? + +### Analysis of Model Appropriateness + +- When do we use each of the models above? + +### Distribution Models (If time permits) + +- Fuzzy Clusters +- EM (Expectation Maximization) Clustering +- Maximum Likelihood Gaussian +- Probabilistic Hierarchal Clustering + + + + +## Textbooks + +Cluster Analysis 5th Edition + +- Authors: Brian S. Everitt, Sabine Landau, Morven Leese, Daniel Stahl +- ISBN-13: 978-0470749913 +- Cost: Free on UMW Library Site +- Amazon Link: https://www.amazon.com/Cluster-Analysis-Brian-S-Everitt/dp/0470749911/ref=sr_1_1?ie=UTF8&qid=1509135983&sr=8-1 +- Table of Contents: http://www.wiley.com/WileyCDA/WileyTitle/productCd-EHEP002266.html + +Cluster Analysis: 2014 Edition (Statistical Associates Blue Book Series 24) + +- Author: David Garson +- ISBN: 978-1-62638-030-1 +- Cost: Free with Site Registration +- Website: http://www.statisticalassociates.com/clusteranalysis.htm + + + +## Schedule + +In an ideal world, the topics below I estimated being a certain time period for learning them. Of course you have more experience when it comes to how long it actually takes to learn these topics, so I'll leave this mostly to your discretion. + +**Distance, Dimensionality Reduction, and Tendency** -- 3 Weeks + +**Validating Cluster Models** -- 1 Week + +**Connectivity Models** -- 2 Weeks + +**Cluster Evaluation** -- 1 Week + +**Centroid Models** -- 3 Weeks + +**Density Models** -- 3 Weeks + +**Analysis of Model Appropriateness** -- 1 Week + +The schedule above accounts for 14 weeks, so there is a week that is free as a buffer. + +## Conclusion + +Creating this document got me really excited for this independent study. Feel free to give me feedback :) \ No newline at end of file diff --git a/static/files/research/ExpeditedLearningInteractiveDemo.pptx b/static/files/research/ExpeditedLearningInteractiveDemo.pptx new file mode 100644 index 0000000..739ea7a Binary files /dev/null and b/static/files/research/ExpeditedLearningInteractiveDemo.pptx differ diff --git a/static/files/research/LUNAC.pdf b/static/files/research/LUNAC.pdf new file mode 100644 index 0000000..12ac30c Binary files /dev/null and b/static/files/research/LUNAC.pdf differ diff --git a/static/files/research/LUNACposter.pdf b/static/files/research/LUNACposter.pdf new file mode 100644 index 0000000..675ff16 Binary files /dev/null and b/static/files/research/LUNACposter.pdf differ diff --git a/static/files/research/Measuresofsimilarity.pdf b/static/files/research/Measuresofsimilarity.pdf new file mode 100644 index 0000000..9c30b26 Binary files /dev/null and b/static/files/research/Measuresofsimilarity.pdf differ diff --git a/static/files/research/QEP.pptx b/static/files/research/QEP.pptx new file mode 100644 index 0000000..88a55ea Binary files /dev/null and b/static/files/research/QEP.pptx differ diff --git a/static/files/research/TheBanditReport.pdf b/static/files/research/TheBanditReport.pdf new file mode 100644 index 0000000..c9eac4b Binary files /dev/null and b/static/files/research/TheBanditReport.pdf differ diff --git a/static/files/research/coherentcontrolofatomicpopulation.pdf b/static/files/research/coherentcontrolofatomicpopulation.pdf new file mode 100644 index 0000000..7b7547d Binary files /dev/null and b/static/files/research/coherentcontrolofatomicpopulation.pdf differ diff --git a/static/files/research/honorsthesis.pdf b/static/files/research/honorsthesis.pdf new file mode 100644 index 0000000..7a1a64c Binary files /dev/null and b/static/files/research/honorsthesis.pdf differ diff --git a/static/files/research/modellingpopulationdynamics.pdf b/static/files/research/modellingpopulationdynamics.pdf new file mode 100644 index 0000000..b8ad0f8 Binary files /dev/null and b/static/files/research/modellingpopulationdynamics.pdf differ diff --git a/static/files/slides/embezzlement.pdf b/static/files/slides/embezzlement.pdf new file mode 100644 index 0000000..2445365 Binary files /dev/null and b/static/files/slides/embezzlement.pdf differ diff --git a/static/files/slides/similyrics.pdf b/static/files/slides/similyrics.pdf new file mode 100644 index 0000000..be5768f Binary files /dev/null and b/static/files/slides/similyrics.pdf differ diff --git a/static/files/umwlug/audio.pdf b/static/files/umwlug/audio.pdf new file mode 100644 index 0000000..4acd857 Binary files /dev/null and b/static/files/umwlug/audio.pdf differ diff --git a/static/files/umwlug/darklogo.pdf b/static/files/umwlug/darklogo.pdf new file mode 100644 index 0000000..12e1a78 Binary files /dev/null and b/static/files/umwlug/darklogo.pdf differ diff --git a/static/files/umwlug/interestfall2018.pdf b/static/files/umwlug/interestfall2018.pdf new file mode 100644 index 0000000..597b93f Binary files /dev/null and b/static/files/umwlug/interestfall2018.pdf differ diff --git a/static/files/umwlug/interestfall2019.pdf b/static/files/umwlug/interestfall2019.pdf new file mode 100644 index 0000000..fe00b3b Binary files /dev/null and b/static/files/umwlug/interestfall2019.pdf differ diff --git a/static/files/umwlug/interestspring2018.pdf b/static/files/umwlug/interestspring2018.pdf new file mode 100644 index 0000000..1029429 Binary files /dev/null and b/static/files/umwlug/interestspring2018.pdf differ diff --git a/static/files/umwlug/interestspring2019.pdf b/static/files/umwlug/interestspring2019.pdf new file mode 100644 index 0000000..585fda7 Binary files /dev/null and b/static/files/umwlug/interestspring2019.pdf differ diff --git a/static/files/umwlug/linuxvunix.pdf b/static/files/umwlug/linuxvunix.pdf new file mode 100644 index 0000000..7ad9393 Binary files /dev/null and b/static/files/umwlug/linuxvunix.pdf differ diff --git a/static/files/umwlug/logo.pdf b/static/files/umwlug/logo.pdf new file mode 100644 index 0000000..0af54a3 Binary files /dev/null and b/static/files/umwlug/logo.pdf differ diff --git a/static/files/umwlug/petertalk.pdf b/static/files/umwlug/petertalk.pdf new file mode 100644 index 0000000..4252daf Binary files /dev/null and b/static/files/umwlug/petertalk.pdf differ diff --git a/static/files/umwlug/tedtalk.pdf b/static/files/umwlug/tedtalk.pdf new file mode 100644 index 0000000..98bb926 Binary files /dev/null and b/static/files/umwlug/tedtalk.pdf differ diff --git a/static/img/avatar.jpg b/static/img/avatar.jpg new file mode 100644 index 0000000..d2211a1 Binary files /dev/null and b/static/img/avatar.jpg differ diff --git a/static/img/favicon.ico b/static/img/favicon.ico new file mode 100644 index 0000000..45008d3 Binary files /dev/null and b/static/img/favicon.ico differ diff --git a/static/keybase.txt b/static/keybase.txt new file mode 100644 index 0000000..a3fbedb --- /dev/null +++ b/static/keybase.txt @@ -0,0 +1,52 @@ +I hereby claim: + + * I am an admin of https://brandonrozek.com + * I am brozek (https://keybase.io/brozek) on keybase. + * I have a public key ASC0uPV8wQGhrA_JFkaY6D5SL6CRDzAttViMipmFf1EOKwo + +To do so, I am signing this object: + +{ + "body": { + "key": { + "eldest_kid": "0120b4b8f57cc101a1ac0fc9164698e83e522fa0910f302db5588c8a99857f510e2b0a", + "host": "keybase.io", + "kid": "0120b4b8f57cc101a1ac0fc9164698e83e522fa0910f302db5588c8a99857f510e2b0a", + "uid": "b0a95fe14c44e3d6e1ef5ea1db76ab19", + "username": "brozek" + }, + "merkle_root": { + "ctime": 1562016085, + "hash": "9d7341ba1f1f7ead60bbe053b2225a0da4e176a1f01ad03028b44e2de63fbf336b13020603665a2fb03925b9bca198fbcd1afbcfdc48890174ed853cc29180f2", + "hash_meta": "35592527e7fa28f64e609af892ddb7037dda26e0878fde7962ce0a0ed60323b8", + "seqno": 5675461 + }, + "service": { + "entropy": "QwM0YfSruvMgRiQV2182C6pZ", + "hostname": "brandonrozek.com", + "protocol": "https:" + }, + "type": "web_service_binding", + "version": 2 + }, + "client": { + "name": "keybase.io go client", + "version": "4.1.0" + }, + "ctime": 1562016093, + "expire_in": 504576000, + "prev": "1ea3c48ec49efb4b553666f56bd00cb0e72ae392d7e23ec08b0bc328e969c7e8", + "seqno": 10, + "tag": "signature" +} + +which yields the signature: + +hKRib2R5hqhkZXRhY2hlZMOpaGFzaF90eXBlCqNrZXnEIwEgtLj1fMEBoawPyRZGmOg+Ui+gkQ8wLbVYjIqZhX9RDisKp3BheWxvYWTESpcCCsQgHqPEjsSe+0tVNmb1a9AMsOcq45LX4j7AiwvDKOlpx+jEIFxHhuW7Qvb5oaOYfQoajEH+4c6mibK2jItcswgs3dCHAgHCo3NpZ8RAJ2Zyb+G2p6WYAlp9hZ5kH1/A1hI6CEBpMezqTvrBSolFBanObkYFSemGHh3vCUDgRJRT96HyA/J4fIGqf6MxDKhzaWdfdHlwZSCkaGFzaIKkdHlwZQildmFsdWXEIC7Cc/7oKz5F/YYU7PGRgxD4HPxOqUnhqT+PYC7zlp5Vo3RhZ80CAqd2ZXJzaW9uAQ== + +And finally, I am proving ownership of this host by posting or +appending to this document. + +View my publicly-auditable identity here: https://keybase.io/brozek + +