Saturday, December 27, 2014

Randomized algorithms: Verifying matrix multiplication

Another great example of randomized algorithms in the introductory chapters of the book "Probability and Computing" is verifying matrix multiplication. Suppose we have 3 matrices of compatible dimensions $A, B$, and $C$, and we want to verify that
\[A\cdot B = C\]

For simplicity, let's assume that all the matrices are square, and of dimension $n \times n$. The straightforward way to do the verification is to explicitly multiple the matrices $A$ and $B$ together, an operation that is of the order of magnitude of $O(n^3)$.

As an aside, we can do better than $O(n^3)$ for matrix multiplication for larger matrices. Wikipedia has an excellent writeup on Strassen's algorithm which accomplishes matrix multiplication in $O(n^{2.8074})$ through divide and conquer. First the matrices $A$, $B$, and $C$ are padded with zero columns and rows so that their dimensions are of the form $2^m \times 2^m$. The matrices are then divided into equally sized  block matrices of the form:
\[ A = \left[ \begin{array}{cc} A_{1,1} & A_{1,2} \\ A_{2,1} & A_{2,2} \end{array} \right] \]
\[ B = \left[ \begin{array}{cc} B_{1,1} & B_{1,2} \\ B_{2,1} & B_{2,2} \end{array} \right] \]
\[ C = \left[ \begin{array}{cc} C_{1,1} & C_{1,2} \\  C_{2,1} & C_{2,2} \end{array} \right] \]
\[ C_{i,j} = \Sigma_{k=1}^2 A_{i,k} B_{k,j} \]
The trick of the Strassen's algorithm is decreasing the number of required multiplications (8) by defining the auxiliary matrices $M_i$ such that:
\[ \begin{eqnarray}
M_1 & = & (A_{1,1}+A_{2,2})(B_{1,1}+B_{2,2}) \\
M_2 & = & (A_{2,1}+A_{2,2}) B_{1,1} \\
M_3 & = & A_{1,1}(B_{1,2}-B_{2,2}) \\
M_4 & = & A_{2,2}(B_{2,1}-B_{1,1}) \\
M_5 & = & (A_{1,1}+A_{1,2})B_{2,2}\\
M_6 & = & (A_{2,1} - A_{1,1})(B_{1,1}+B_{1,2}) \\
M_7 & = & (A_{1,2} - A_{2,2})(B_{2,1}+B_{2,2})

which have $7$ multiplications instead, and expressing the result in terms of the  $M$ matrices as:
C_{1,1} & = & M_1 + M_4 - M_5 + M_7\\
C_{1,2} & = & M_3 + M_5 \\
C_{2,1} & = & M_2 + M_4 \\
C_{2,2} & = & M_1 - M_2 + M_3 + M_6

The algorithm continues to divide matrices $A$, $B$, and $C$ into smaller blocks in a similar manner until there is only one element, and the multiplication becomes straightforward.

There are faster algorithms for matrix multiplication, such as the Coppersmith–Winograd algorithm with complexity of $O(n^{2.375477})$ and yet faster ones with $O(n^{2.3728639})$, but what if these are not fast enough?

Randomized algorithms come to the rescue. The idea is to choose a vector $r$ of dimension $n$, whose elements $r_i \in \{0,1\}$ and compute the quantities $ABr$ and $Cr$. If $ABr \ne Cr$ then $AB \ne C$ and the verification of matrix multiplication is done.

On the other hand if $ABr = Cr$ then either $AB=C$ or we might have a false positive. The false positive occurs when $(AB-C)r=0$, with the first term in the equation $AB-C$ not zero. The book computes the probability of this happening as less than $\frac{1}{2}$. The argument goes as follows.

Define the first term as a matrix $D=AB-C$. Since $D \ne 0$ in the false positive case, it must contain a non-zero element somewhere in the matrix. Assume this element is $d_{11}$.  We can then write $Dr=0$ as the set of $n$ simultaneous equations:

\[ \Sigma_{j=1}^{n} d_{ij}r_j=0 \]

Or for $r_1$ in the false positive case

\[ r_1 = -\frac{\Sigma_{j=2}^{n} d_{1j}r_j}{d_{11}} \]

Using the principle of deferred decisions we can figure out the probability of the false positive. We start by selecting $r_i$ for $i \in \{2, n\}$ randomly and independently from the set $\{0,1\}$, and we pause before selecting $r_1$ from the same set.  Since $r_1$ can have one of two values $\{0,1\}$, the probability of selecting $r_i$ that satisfies the prior equation to give us the false positive case is $\frac{1}{2}$

Since a false positive probability of $\frac{1}{2}$ is not good enough, we can repeat the algorithm with a new random vector $r$. After $k$ repetitions of the algorithm the false positive probability drops to $\frac{1}{2^k}$, which we can make small to our liking with many repetitions. The cost of the verification algorithm is on the order of $O(kn^2)$ multiplications, which is better than the fastest direct algorithm for explicit matrix multiplication.

Saturday, December 20, 2014

Classic Algorithms: Page Rank and the importance of web pages

Think of a search query, and go to your favorite search engine and conduct the search. Of the millions of matching documents returned, it is most likely that the first page or two contain what you are looking for. Have you ever wondered how the search engines know how to present the most relevant results for us in the first couple of pages, when all the results returned match the query we were looking for?

There are a lot of signals search engines use to determine the importance of the matched results: some are intrinsic to the page such as where in the page the match occurs, whether it is highlighted or not, and the importance of the web page; and some are extrinsic such as how many users clicked on the result for a similar query. The signals, their weights, and the formulas to rank the results are usually guarded secrets by search engines as they are the secret sauce for giving users the best results to their queries.

One such signal is the importance of a web page. How would you compute that? In 1996, Larry Page and Sergey Brin came up with a way called PageRank. The idea they proposed is that in a connected graph structure such as the world wide web, the importance of a web page is related to the importance of other web pages that point to it. If we denote the importance of a web page, or its PageRank by $r_i$, Page and Brin proposed that \[ r_i = \Sigma_{j \in N} \frac{r_j}{d_j}\] where $N$ is the set of pages that link to page $i$, $r_j$ is the PageRank for each of the pages that point to $r_i$, and $d_j$ is the number of outgoing links for each $r_j$ page.

If we write these equations for every node on the web, we come up with a system of simultaneous linear equations that we can solve, and get the PageRank for each web page. We can also write the simultaneous equations in vector and matrix notations as:
 \[ \mathbf{r} = \mathbf{M r} \]
where $\mathbf{r}$ is the vector of PageRanks for all the web pages, and $\mathbf{M}$ is the matrix whose column entries are either $0$ or $\frac{1}{d_j}$ for pages that link to page $i$.

It turns out that by rewriting the PageRank problem in this form, we discover that it resembles the eigenvalue/eigenvector problem in linear algebra, with the PageRank $\mathbf{r}$ as the eigenvector corresponding to an eigenvalue of $1$. There are many ways to solve the eigenvalue problem, and the power method is one of them: where we start with an initial value of the PageRank $\mathbf{r}^{(0)}$, and compute subsequent values through:
\[ \mathbf{r}^{(t+1)} = \mathbf{M} \mathbf{r}^{(t)}\]
until convergence occurs, i.e. the difference between the PageRanks in two subsequent iterations becomes very small:
 \[ \| \mathbf{r}^{(t+1)} - \mathbf{r}^{(t)} \|_n < \epsilon \]
where $\|\cdots\|_n$ is the $L_n$ norm, and $\epsilon > 0$. Typically the Euclidean or $L_2$ norm is used.

There is a wrinkle in the simultaneous equations or eigenvalue/eigenvector formulations of the PageRank though: not all simultaneous equations or eigenvalue/eigenvector problems are well posed to have a solution. This happens for example when you have linear dependence between the equations or rows/columns of the matrix. An illustrative example would be a sink page, which does not have any outbound links to any other pages. Its effect on the PageRanks of other pages would be zero, and all the respective columns in the matrix $\mathbf{M}$ associated with the page would be $0$. Another example would be a page that links to itself, where during the power iteration, all the other page PageRanks are leaked to $0$. How would you tackle such problems? Through a bit of creativity.

It turns out that if we model browsing the Internet as a random walk over its connected graph structure,  where a random surfer moves from page $i$ to another page, by following one of the outbound links from page $i$, we arrive at a similar formulation

\[ \mathbf{r}=\mathbf{Mr} \]
as before.

Of course the random surfer would not stop when there are no outbound links in the page they are at, and would whimsically go to any other page on the Internet. The model is then augmented to accommodate such behavior:

\[ \mathbf{r} = \beta \mathbf{Mr} + \frac{(1-\beta)}{N}\mathbf{r} \]

where $0<\beta<1$, and $N$ is the total number of pages in the web graph. The first term in the equation models the random surfer picking one of the outbound links at random to visit a subsequent page, and the second term models them jumping to any other page on the Internet at random.

We can rewrite the prior formulation as:

\[\mathbf{r} = \mathbf{M'r} \]

which is well formed, and has a solution since $\mathbf{M'}$ is a stochastic matrix. Using the power method on the last equation will yield the PageRanks $\mathbf{r}$ of all the web pages in the Internet.

Of course that computation requires a lot of engineering magic, since there are billions of web pages on the Internet, and each have many outbound connections.

Thursday, December 11, 2014

Randomized Algorithms: Polynomial equivalence

We are all accustomed to deterministic algorithms; we work with them every day, and feel comfortable in knowing that the results of running them are predictable, barring a coding error of course. The idea of randomized algorithms feels remote and uncomfortable, despite their usefulness and elegance.  There are a couple of great examples in the introductory chapters of the book "Probability and Computing" that are an eye opener.

One is verifying polynomial identities: how can you tell that two different representations of polynomials are the same? For example, if we have two polynomials $P(x)$ and $Q(x)$, both of degree $d$ described by the following formulas:
P(x) = \Sigma_{i=0}^{i=d} a_i x^i \\
Q(x) = \Pi_{i=1}^{i=d} (x-b_i)

how can we determine that they are the same polynomial?

Intuitively we first check that the degrees are the same, then we could try to transform one form into the other, either by multiplying out the terms for $Q(x)$, collecting like terms and reducing it to $P(x)$, or finding the $d$ roots $r$ of $P(x)$, and expressing it as a product of $d$ terms of the form $(x-r_i)$ and comparing them to $Q(x)$. The first approach is easier, but can we do better?

The book presents a randomized algorithm to do the same. What if we pick a random number $r$ from the range $[0, Nd]$, where $N$ is a natural number greater than zero. For example if $N$ is $100$, we pick a random number $r$ from the range $[0,100d]$, and evaluate $P(r)$ and $Q(r)$, which could be done in $O(d)$ time. What would the result tell us?

If $P(r) \ne Q(r)$ then the polynomials are not the same. If $P(r) = Q(r)$, then there is a chance that the polynomials are equivalent, but there is also a chance that they are not, and that $r$ in this case is a root of the equation $P(x)-Q(x)=0$. The chance that we picked an $r$ that satisfies the last equation is no more than $1/N$---($1/100$ in the concrete example).

How do we minimize that chance? By repeating the evaluation by drawing another random value $r$ from the interval $[0,Nd]$. The book describes the probability of producing a false result as the evaluations are repeated with and without replacement, and they are less than $(1/N)^k$, where $k$ is the number of evaluations.

Isn't it quite elegant to find out that two polynomials are the same or not simply through repeated evaluations, and not through algebraic manipulations to transform either or both to a canonical form?

Monday, December 8, 2014

Down memory lane: Approximate counting

At work we do a lot of counting. For some counts we need an accurate result, while for others we can get by with an approximate count. For these approximate counts, as long as the result is within the same order of magnitude of the true count, we're ok.

There is a lot of literature on approximate counting techniques, and the blog post "Probabilistic Data Structures for Web Analytics and Data Mining" does a great job at explaining some of them in detail, with references to the original papers.

One of the original approximate counting papers was the 1978 paper: Counting large numbers of events in small registers by Robert Morris. In the paper Morris explains the context for the problem, which might seem foreign today. Back in 1978 he was faced with the problem of counting a large number of different events, and because of memory restrictions he could only use 8-bit registers for each counter. Since he was not interested in exact counts, but with accurate enough counts, he came with the technique of probabilistic counting.

The first solution he explored in the paper was to count every other event based on a flip of a coin. If the probability of the coin flip is $p$, for a true value $n$, the expected value of the counter is $n/2$, with a standard deviation of $\sqrt{n/4}$. The error for such a solution is high for small values of $n$.

Morris then presents his second solution, by introducing a counter that stores the logarithm of the number of events that have occurred $v$, and not the raw count of the events. He increments the counter value $v$ probabilistically based on a flip of a coin. The stored value in the counter is $\log{1+n}$ and the probability of increasing the counter is $1/\Delta = \exp{(v+1)}-\exp{(v)}$.

The paper is an enjoyable short read, and it is amazing that the techniques introduced in the 70's are still applicable to technology problems today.

Saturday, November 22, 2014

React conference in San Francisco 2014

Last week I attended the React conference in San Francisco. The conference is a two day event where speakers share their experiences on building reactive systems: ones that are resilient, elastic, responsive, and message driven. The reactive manifesto web page  has more detailed information about reactive systems, and why they are useful.

This year the conference was at Cobb's Comedy Club, a cozy venue for the roughly 300 people that attended the conference. Because of the tight space, power plugs were non existent, but the organizers were extremely thoughtful and provided every attendee with a rechargeable battery with iPhone and Android connectors.

The sessions in the conference were great, but a couple stood out. The first was Netflix's presentation "Resilient by Design", where the speaker talked about how Netflix designs and deploys their services: from using microservices that do one thing and do it very well with well defined interfaces, to cloud services everywhere, and thinking about failures and how to degrade gracefully when they happen. The speaker gave an example of the Netflix homepage, where every component from the movie recommendations, to the most popular movies, to the video bookmarking functionality is a service, and that when one of them fails, there is always a meaningful fallback that still allows the user to have a decent experience.

The second was the talk by Gil Tene from Azule systems about "Understanding Latency." The speaker gave great examples of how myopic statistics are deceiving, and how timing measurements in general suffer from mistakes of omission, especially when one request stalls and takes a long time to finish.

The third was the talk by Leslie Lamport about how to specify systems formally through TLA+. The talk was both entertaining and informational at the same time. Lamport admitted that engineers and their managers are allergic to formal specifications, and that they don't see value in them. He then gave a taste of what formal systems are, what they can help with, and  proceeded with counter examples to debunk the myth that formal specs are not useful. Some of the counter examples were discovering design problems that would have been very costly to fix in  Chord, dynamoDB and other Amazon web services, cache coherence in the alpha chip, and the XBox 360 memory model.

Hopefully the conference talks will be online on youtube for others to enjoy the talks as much as the conference attendees did.

Saturday, September 20, 2014

Mining the Social Web, by Mathew Russell, O'Reilly Media

"Mining the social web" is a book about how to access social data from the most popular social services today by using the services' public APIs, and analyzing the retrieved data to gain insights about it.

The book uses the Python programming language to access and manipulate the data, and provides code snippets of common tasks within the book, as well as full iPython notebooks on Github. The book is written as documentation for the freely available iPython notebooks, with the documentation providing context and background for the code, as well as describing the algorithms used to mine the social data.

The author tries to be as concise as possible, although he did not succeed in the first chapter, where the first three section were verbose, and relatively unnecessary,  describing what twitter is and why people use it as a microblogging platform. With that out of the way, the writing style improves as the book progresses, and is a mixture of code examples and step by step explanations.

The author follows the same formula throughout the book: for each of the popular social services examined, he starts with an overview of the API to access the required data and how to configure the requisite authorization tokens to access it. He then proceeds to explain how to make requests, followed by a brief description of the important APIs and data sets returned. The author then presents a couple of algorithms to mine the data, and extract valuable statistics from it, describing the algorithms without assuming prior knowledge on the reader's end. Finally the author presents a cool visualization of the insights, using either Python libraries and packages, or Google Earth APIs. The formula is quite useful, and provides the book with consistency across chapters, which can be read independently and out of order.

The author starts with Twitter. He explains the structure of Twitter API, how it uses OAuth, and how to connect with it using the python "twitter" library. The chapter progresses with example python notebooks that show how to retrieve trending topics, user timelines, search results, and manipulate the tweet contents and tweet locations to gather interesting statistics about them. The writing style is expository, showing the notebooks piecemeal and explaining them well.

In the next chapter, the author focuses on Facebook and the social graph API. The chapter starts with an exposition of the entities available through Facebook (timeline, likes, locations, etc), how to grant access tokens to each of these entities, and introduces the Facebook query language FQL. The author provides ample examples that analyzes social graph connections, Facebook pages (Pepsi vs Coke examples), statistics on friends likes, and Friend graph cliques using PrettyTables, Histograms, and graph plots.

The author then tackles LinkedIn in a similar manner, but starts introducing the more interesting data mining techniques with a brief introduction to data clustering clustering algorithms. The author talks about normalizing the data, using NLTK for language processing, and describes and uses a couple of clustering algorithms such as greedy and hierarchical clustering, and k-means to cluster LinkedIn connections. The chapter ends with cool visualization of where the talent is using Google Earth.

The author then proceeds to Google+, and describes an information retrieval example to cluster documents, using it to introduce concepts such as TF-IDF, document similarity, and analyzing language bigrams.

The next chapters are about understanding blog posts, with a brief interlude on how to crawl and scrape the web, and how to summarize documents, which comes in handy if you have no time to read the full content of web pages and you'd like to figure out the gist of the document.

The following chapter tackles mining user emails, including high level statistics on who connects to who, and how frequently do they send emails to each other. The author uses the Enron data as an example, and introduces a toolkit to do the same with Gmail accounts

The last couple of chapters deal with Github project analytics, and micro formats and RDF. The book ends with a cookbook of recipes that list the problem to be solved, offers a solution, and discusses the salient points of the solution to drive a point home. Most of the cookbook recipes are for twitter, with a couple of cases for Facebook.

Overall I recommend the book. It is decently written, and contains a wealth of introductory material on how to access content from the popular social websites, and a cornucopia of algorithms that can be used to analyze the data.

Tuesday, September 2, 2014

Can you make me a Cortado please?

A couple of months ago I stumbled upon an info graphic that depicts popular coffee drinks around the world, and thought I'd give some of these drinks a try. I started with the cortado: a drink that is popular in Spain, Portugal, and Columbia, and consists of one part espresso, and one part steamed milk.

Almost every coffee shop that I went to had no idea how to make the drink, and it became a great conversation starter with the coffee barista, describing where I stumbled upon the recipe, and what other coffees are popular in different regions of the world.  I was pleasantly surprised when one barista at Peet's coffee knew how to make the drink from his travels to Spain. He also suggested modifications to the drink that would make it more delicious including using whole milk instead of 2%, adding another shot of espresso, and sweetening the drink with one pack of brown sugar. The final combination is my current favorite.

Migrating from the Macbook Air to the Macbook Pro

My Macbook Air started to show wear and tear after a couple of years of heavy use. Five of the keys on the keyboard broke and had to be replaced, despite my light touch typing--honestly, and the battery has moved from the warning that it needs service to retaining electric charge for shorter and shorter periods of time, to not holding a charge at all.

For my next device I contemplated getting another Macbook Air with the highly enviable 12hr battery life, or switching back to a 15 inch Macbook Pro, and enjoying a more powerful machine, with a retina display and a respectable 8 hours of battery life. The prospect of more screen real-estate, and more processor power was too enticing, so I ended up getting the Macbook Pro despite the weight difference.

Since I accumulated 3+ years worth of data and software on the Air, I did not want to repeat the process of reinstalling apps from scratch and searched for an easy way to migrate the data to the new machine.  Most of the online recommendations were to use the Migration Assistant during the initial install phase. I decided to give it a try. I ran through the install process, created an account on the new new Macbook Pro, and started the Migration Assistant on the old Air and the new Pro. I chose migration over Wifi since I did not have a firewire cable handy, which turned out to be a mistake. Either due to a bug or an unreliable Wifi connection, the migration assistant would crash on both computers when it tried to migrate data between the machines.

I did not give up on the Migration Assistant, and decided to try another method: migration using a Time Machine backup. I took a full backup of the Macbook Air, which took roughly 8 hours to finish, and used the Migration Assistant to transfer that to the new Pro. The migration initially failed since my user name existed on the new machine--an easy fix by renaming the user, but then after starting the migration again,  the data copying was stuck for almost 11 hours with no progress. A quick search online revealed that this is a widespread problem, and not an isolated instance.

I decided to try my luck elsewhere. Although Apple does not recommend restoring a computer from a backup of another computer, I decided to give that a try,  especially since some of the applications I have installed including VPN and MacPorts store their data in non-standard locations.

I booted the new Macbook Pro in recovery mode, and  chose restore from Time Machine. I left the machine running overnight--the full restore took about 6 hours to finish, and by the end I had an identical setup to the one I had on the Macbook Air. I had to re-enter my license information for my applications, and apart from a couple of minor glitches with the Kindle App, and iCloud accounts which were easy to fix, everything worked like a charm, and I am very pleased with the result.

Hopefully I won't need to migrate computers anytime soon, but if I have to, now I know how to do it using Time Machine backups.

Monday, September 1, 2014

Fitbit bands

I am fairly disappointed in the quality of the Fitbit flex bands. After a couple of months of moderate use, the bands developed deep cracks and finally broke. There are a lot of accounts online and on Facebook from Fitbit users who have experienced similar issues, so the problem is widespread and not isolated.

What makes matters worse, is that after ordering and getting a replacement band from Fitbit, a rash developed on my skin. I did not experience a rash with the prior band color, and my guess is that the material is different from the original one I had.

Now I have two choices, either get another replacement band with the original color, and hope that it does not cause a rash, or give up on the Fitbit completely, and wait for some of the newer health tracking technologies around the corner. An iWatch perhaps?

Monday, May 26, 2014

First impressions of the Fitbit Flex

Many years ago I bought a pedometer to help me count the number of steps that I take on a daily basis. The idea was to walk at least ten thousand steps every day to balance the modern sedentary lifestyle, caused by sitting on a chair almost all day long, both at work and at home. The pedometer was great for a while, showing how far I was from the ideal number of steps, and making me compete with myself every day to increase the number of steps I take. Because it was bulky and inconvenient to carry in my pocket, when I finally hit the goal of ten thousand steps I stopped carrying it along. And of course the number of steps declined back to where it was before the pedometer, and I did not think anything of it.

This year the flu season has not been kind to me. Between a hectic work schedule and a kid at daycare, I have been hit by some cold or flu variant every couple of weeks. My wife attributed the low immunity to a lack of physical activity, and she started looking for a way to help us become more active again. She settled on the Fitbit Flex, because of the good reviews, and the fact that the Fitbit Force was recalled since it caused a skin rash. As a bonus, we could see how many steps we were taking, and compete with each other to encourage a more active lifestyle.

Setting the Fitbit was a breeze, and the web interface is intuitive and straightforward. Through the interface we discovered more functions that the Fitbit supports. In addition to logging steps, the Fitbit supports logging sleep, calorie intake, water intake, and active minutes. And as a bonus, the dashboard allows us to compare performance with people we add from the Fitbit community.

The Fitbit is more convenient to wear than the pedometer, but definitely less convenient for someone who wears a watch since it adds another band to either hand. I wish it had a watch like the Force, but I understand why Fitbit wanted a smaller feature set on the device for a better battery life. Which is great: roughly 5 days on a recharge, and the charging takes about a couple of hours using the computer's USB port.

Overall I am satisfied with the Flex, and I have found the dashboards to be very convenient, and a good incentive to be more active. There is something to be said about the quantified self movement going on after all.

Monday, February 17, 2014

Juice diets and the Vitamix

Over the weekend I watched "Fat, sick, and nearly dead", a documentary on Netflix about how a sick and overweight Australian regained his health by following a strict juice diet for about 6 months augmented by moderate exercise. The documentary tracks his progress over the 6 months period, as he travels throughout the US from coast to coast, talking to people about the health benefits of the juice diet, and showing them how it affected his health. The documentary also shows how toward the end of his diet, he started evangelizing it, and helping other people reverse their heavily medicated health problems by following a similar diet and moderate exercise.

The documentary was very well made, and the author is quite likable. It was also very educational about the types of foods people consume, and the nutrients they get out of them: micro-nutrients--those that come from plant sources, and macro-nutrients--those that come from animal sources. The documentary's thesis is that we are facing most of the modern health issues because our diet is biased toward animal sources, which provide us with only the macro-nutrients, and we miss out on all the goodness of the micro-nutrients. If we consumed more of the latter,  our health issues would go away, since our bodies know how to heal themselves if we get out of the way.

Since I am guilty of consuming mostly animal products, and shying away from anything green and fruits in general, I decided to try augmenting my food with intake of micro-nutrients. And since I am not a big fan of consuming them raw or cooked, I thought that getting them in the form of juice would make their consumption quite easy. And for that, I needed a blender that would turn fruits and vegetables into juice easily.

There are a lot of options on the market, but almost everyone I know sang praises for the Vitamix products. These blenders are rather expensive, but they are very powerful--equipped with a roughly 2 HP motor, are very durable, and are convenient to use and relatively easy to clean. I decided to get one, and it arrived promptly.

Excited, we went to the grocery store for some serious shopping of everything colored green, and a plethora of fruit. The experimentation began.

The first concoction was a random selection of oranges, bananas, carrots, kale, apples, and blueberries. After blending, the mixture had the unappealing color of duck poop, but despite the unappetizing color, the drink was relatively tasty, and most definitely filling. We ended up not eating lunch because the bananas made us quite full.

Encouraged by the results of the first batch, we decided to go green, and made another batch with cucumbers, celery, spinach, green peppers, a lime, and an apple. This time the result had an appetizing green color, and the texture and consistency were much better.  However, the taste was not good; it felt like eating a suspended finely chopped salad without the salad dressing or the chewing, and every sip sent shivers down our spines. We need better recipes. The juice of course obviated the need for dinner, and we were quite satisfied without the meal.

The next day we decided to do something more conventional: orange juice with a hint of apple. The mixture color was very appealing, just like orange juice, but much thicker, and definitely quite filling. It did not substitute breakfast, but we definitely ate much less than we usually do. There is something to this juicing after all.

I am looking forward to more experiments and concoctions, but I feel that we need to find good recipes so that the result is both edible and appealing. As to how augmenting our meals with juice will affect our health, we have to wait and see.

Saturday, January 11, 2014

Sonos Play:5

Over the holiday season I was looking for a speaker with a decent sound quality, and good support for playing music wirelessly. With a bit of research I settled on the Sonos Play:5 speaker. Most of the online reviews were favorable, and it supported streaming online music from Spotify, Pandora, and a dozen other services. The speakers were also on display at Target stores for a live test, and despite the background noise in the store, they sounded great. Sonos was running a promotion at the time, where you got a free bridge with the purchase of any of their speakers, which is a decent discount.

Setup was extremely easy. I plugged the bridge into my wifi router, plugged the speaker into a power outlet, and installed the Sonos application on my computer. The application guided me through the intuitive setup, which involved pressing a button on the bridge, and another on the speaker to connect the whole system together.  After that it was time to play music.

The Sonos application imports pre-existing music stored on the computer, including these managed by iTunes, in addition to providing streaming service through online providers. The application manages the streaming, so you have to provide your username and password to the application, and it streams music on your behalf.

I tried Pandora--the free account, and despite the low bit-rate the music was great. For Spotify premium--high bit-rate--the sound was amazing.

The application includes nice features such as a timer, and an alarm, as well as the easy control of multiple speaker groups, and defining speaker stereo groups. The app also has versions for the iPhone and the iPad that provide the same functionality as the desktop app.

I am very pleased with the sound quality even with one speaker, and I would highly recommend it. And perhaps by the next holiday season I would have added another one.