## Friday, May 25, 2012

### Android Remote Control for VLC

This is part of my continuing adventure setting up MythTV at home. (You can find related posts by clicking the MythTV label in the tag cloud on the lower right portion of the page.)  Having set up MythTV, I copied over backups I'd made of my Windows Media Center recordings.  It turns out that they are recorded in a somewhat proprietary format (.dvr-ms file extension).  I'm sure you are as shocked as I am that Microsoft would deviate from the file format standards adopted by, oh, the rest of the world.  At any rate, it is theoretically possible to transcode those files into something like MPEG format, but after one failed attempt I decided not to bother.  These are TV shows I intend to watch once and then delete, and VideoLAN's VLC player, which is available and multiple platforms and a standard part of many (most?) Linux distributions, handles .dvr-ms files nicely.

I've used VLC (frequently) on PCs, but always when I was sitting at the keyboard watching a (typically short) video.  Watching a TV show means sitting at a distance from my TV (and keyboard), so I needed a way to control VLC from a distance.  (It was either that or watch the commercials.)  Enter Remote for VLC, a free VLC remote control app by Peter Baldwin, available for Android devices (such as my Toshiba Thrive tablet) from Google Play (formerly known as the Android store).  There are several VLC remote control apps on Google Play, but this one has one of the highest customer satisfaction ratings, has a very well done interface, and is free.

I have a Wi-Fi network in my house, including the computer running MythTV and VLC, and of course including the tablet.  My version of VLC is "2.0.1 Twoflower".  There are setup instructions for the app online, and I found general instructions for enabling VLC's web interface several places, but not of them exactly matched my setup, so I though I would post my steps here in case they might help someone else.

First, you have to enable the built-in web interface to VLC.  In VLC, click Tools > Preferences, and at the bottom left set Show settings to All.  Expand Interface and select Main interfaces.  Put a check next to Web.  (This is the first place where I had to deviate -- slightly -- from posted help, which mentioned "http".)  Now exit VLC.

Find VLC's .hosts file and open it in your favorite editor.  On my Mythbuntu box, the path is /usr/share/vlc/lua/http/.hosts.  On the PC I'm using right now (Linux Mint), the path is /etc/vlc/http/.hosts, but both /usr/share/vlc/lua/http/.hosts and /usr/share/vlc/http/.hosts symlink to it.  So you may have to do a little detective work, bearing in mind that file names that start with a period are hidden by default (so use ls -a, click ctrl-H in Nautilus, or do whatever is analogous in your file manager of choice).

The troubleshooting instructions say, somewhat vaguely, that you should edit this file after you find it.  Specifically, you need to enable whatever address or range of addresses will be used by your remote control device.  My Wi-Fi network uses non-routable addresses in the 192.168.whatever.whatever range.  So I found the line containing the mask 192.168.0.0/16 and uncommented it by removing the initial hash (#) character, then saved the file.  The file contains masks for all standard private network ranges, so you just need to know what range covers the address your device will be using.  If you will be using a device that is not on the same network as the PC running VLC, you will need to add a line enabling the specific address of the remote device (and make sure the device can communicate with the PC, i.e., that you don't have a firewall that will block the remote device).

Once you have saved the modified .hosts file, start VLC.  (VLC needs to be running so that the remote device can see the built-in web service.)  Make sure your Android device is connected to the network, and start Remote for VLC.  It will scan for VLC servers and, hopefully, find yours and add it to its internal list.  You can tap the menu button in the upper right and select Settings to verify that it is connected and see whether it found your VLC server.

With that, you should be good to go. Have fun exploring the controls.

## Wednesday, May 23, 2012

### K Best Solutions in AMPL/CPLEX

This is a continuation of my earlier post on how to find the K best solutions to a mixed integer linear program. Per a reader request, I'll show how to do it using AMPL+CPLEX. Note that cplexamp is the name of the CPLEX executable that interfaces with AMPL.  The example is that same one from the previous post, a binary knapsack model.

Here's the AMPL code:

#
# K best solutions using AMPL + CPLEX
# Test problem is a binary knapsack
#
# model parameters
#
param n default 20;  # problem size
param k default 3;   # solutions to find
param weight {i in 1..n} := i*sqrt(i);  # item weights
param value {i in 1..n} := i^2;  # item values
param capacity := (2/3)*sum {i in 1..n} weight[i];  # knapsack capacity
#
# parameters controlling the solution process
#
param method in {1,2} default 1;  # method:
# 1=solve MIP, then populate;
# 2=populate only
param intensity in 0..4 default 3;  # CPLEX pool intensity
param limit default 20;     # number of pool solutions to generate
#
# the binary knapsack model
#
var x {1..n} binary;
maximize TotalValue: sum {i in 1..n} value[i]*x[i];
s.t. TotalCapacity: sum {i in 1..n} weight[i]*x[i] <= capacity;
#
# print out solution parameters
#
print "Problem size = ", n, ", seeking ", k, " solutions, method = ",
method, ", intensity = ", intensity, ", limit = ",
limit;
#
# set up CPLEX
#
option solver cplexamp;
option cplex_options ("populate=" & method &
" poolstub=kbpool poolcapacity=" & k &
" poolintensity=" & intensity &
" poolreplace=1 populatelim=" & limit);
#
# solve the model and show the pool solutions
#
solve;
for {i in 1 .. Current.npool} {
solution ("kbpool" & i & ".sol");
display _varname, _var;
}


Most of the CPLEX options can be inferred from the AMPL parameters assigned to them.  There are two I should probably explain:
• poolstub is a file name that CPLEX will use to store each of the solutions in the pool (so in my case I end up with files kbpool1.sol, kbpool2.sol, and kbpool3.sol), which the final loop reads back in; and
• poolreplace tells CPLEX how to decide which solution to boot out of the pool when the pool is full and a new solution is found (value 1 means keep the solutions with the best objective value; other choices are to keep the most recently found solutions or to strive for diversity).
One last note: the .npool suffix (here attached to the current problem) returns the number of solutions in the solution pool at termination (which equals the number of .sol files generated).

Addendum: The last note is apparently not the last note. :-) Guido's comment below reminded me that an important point from the previous post needs to be repeated here (particularly if someone stumbles on this without reading the prior post).  The title of the post notwithstanding, the solution pool approach may not actually produce the K best solutions, unless the population limit is set quite high and the pool intensity is at one of the higher settings.  Both those settings changes are likely to increase solution times.  As was seen in the previous post on this, the moderate settings used in the code example produce several "good" solutions, one of which is optimal, but they do not always produce the second best, third best etc. solutions.

Addendum #2: To answer a question below, we can store the various solutions in a parameter (xx) in the script by adding the following code to the end of the script:

#
# store the solutions
#
param xx {i in 1 .. Current.npool, j in 1 .. n};
for {i in 1 .. Current.npool} {
for {j in 1 .. n} {
solution ("kbpool" & i & ".sol");
let xx[i, j] := _var[j];
}
}
display xx;  # verify what was stored



### MythTV and the Phantom Soundtrack

I previously reported that, having installed Mythbuntu 12.04 and a Hauppauge WinTV-DCR 2650 (and with Comcast as my cable provider), I was getting a spurious soundtrack on one channel (ABC).  When I tested the setup by watching live TV through it, ABC was showing "Spiderman 3", and I was hearing the dialog in Spanish.  It turns out that was the only time I heard Spanish.  Thereafter, whenever I tuned to channel 3 (ABC), the audio was an FM station continuously broadcasting the local weather (?!).  All other stations had the expected audio track.

After considerable poking around, I still don't know why I'm hearing the weather station (or why it was the Spanish dub of Spidey 3 that one time), but I have identified a pattern and a workaround.  It turns out that a random sampling of the stations I tune in (which form a proper subset of the stations available through my Comcast subscription -- my channel list excludes stations I never watch) put them into four categories:
1. some have a single audio track;
2. some have two audio tracks, with no sound on the second track;
3. some have two audio tracks with the same contents on both tracks (at least same to my ears -- if one is higher quality than the other, I'm not detecting it); and
4. ABC (only) has two audio tracks with that weather station on the second track (except, apparently, when it's something else).
In all cases the first audio track has the correct (for me) contents.  Apparently MythTV defaults to the highest numbered track (which is fine for cases 1 and 3) but is smart enough to avoid an empty track when it sees one (so no problem with case 2), which just leaves me with the single instance of case 4.  I don't know if a given station always falls into the same category, or whether in cases 2 and/or 3 the contents of the second track change if, for instance, a movie that has been dubbed into another language is showing.  (Anyone know if any of the "Star Trek" franchise movies have been dubbed into Klingon?)

The pop-up menu (triggered by the 'M' key on the keyboard or the 'Menu' button on the remote) has a submenu to control audio during playback, and for ABC I can use that to switch to the first track.  It's a mild annoyance, but nothing serious.  Searching online yielded other concerns about MythTV defaulting to the highest numbered track, but no solutions other than manually switching.  So for now, at least, I will just have to live with switching audio tracks whenever I replay a recording of an ABC show.

## Saturday, May 19, 2012

### Installing Mythbuntu with WinTV-DCR

A few years back, I bought a tower PC with Windows Vista Media Center (home version) and a tuner card built in.  I've used it almost exclusively as a personal video recorder. For a variety of reasons, Vista has increasingly gotten on my nerves, so I finally bit the bullet and replaced it with MythTV.  The process has taken much longer than I expected, partly due to dopiness on my part, partly due to sketchy instructions here and there (or presumptions that I know things I do not). Herein I chronicle some of the details in case they'll help anyone else. It will be a long post, as it was a long process.

I should note a few more things about my equipment before diving in. I am a Comcast cable customer. I run the incoming cable through a splitter, with one connection to the TV (flat-screen HD) through a set-top cable box and the other to the tuner card in the PC. The PC has an NVidia graphics card (the precise model is, I think, irrelevant) that connects to the TV via an HDMI cable.

The tuner in the PC can only capture analog channels (NTSC), and Comcast is moving more and more channels to digital. So part of the motivation of trying out MythTV was that I needed to install a new tuner in any case. After a little online shopping, I settled on a Hauppauge WinTV-DCR (model 2650), a dual-tuner CableCARD receiver that connects to the PC via USB. The 2650 is not explicitly recognized by MythTV, but according to multiple success stories by other people, you can falsely identify it as an HDHomeRun Prime and it will work fine with MythTV.

My initial thinking was to run Mythbuntu from the DVD, give it a test drive, then install it alongside Vista long enough to confirm that I liked it and to move my existing recordings over. Fortuitously, I took the precaution of copying almost all the recordings to an external hard drive before beginning the experiment. (The "almost" refers to one two-hour recording, approximately 5.3 GB, which could not be copied to the external drive. The issue was not lack of space; apparently the file was too large for the file system -- which might be FAT; I can't recall -- on the drive.)

Like other Ubuntu-based distributions, including Mint, you can boot from the CD or DVD, try out the system, and optionally install it. The test drive is useful to determine whether Mythbuntu correctly identifies and has drivers for your keyboard, mouse, display, network connections etc. In my case, this all worked fine, including installation of the NVidia proprietary drivers. For what it's worth, my keyboard and mouse are wireless, through a hub connect by USB. There was no problem with either of them.

I expected also to test MythTV itself, but as it turns out that cannot be done booting from the DVD. MythTV is a client-server system, so it comes with two parts, a front-end (client) and a back-end (server). You can test MythTV's front-end with a preexisting back-end, but if (like me) this is your first foray into MythTV, you will not have a back-end installed. No back-end, not test.

There was nothing for it but to install Mythbuntu. Mythbuntu initially gave me a screen with three choices, the first being to install alongside Vista. I chose that and took the default choice for disk partitioning. Shortly thereafter, Mythbuntu informed me that one of the partitions (it was not clear which; possibly the swap partition) was too small at the size it had selected itself and that I should back up and make it bigger. So I backed up and got what looked like the "how do you want me to install it" dialog again. Apparently I paid insufficient attention when I clicked the top choice, because this time the top choice was to wipe the old system and install just Mythbuntu. When I realized what it was doing (almost immediately) I ejected the DVD (the only way I could find to stop it), then reinserted the DVD and tried to restart the installation ... only to be told that the hard drive now had no system on it. To paraphrase Captain Keith Mallory, my "bystanding days" were over and I was "in it now up to [my] neck". A full install was on.

Thereafter, installation of Mythbuntu was quick and painless. There were 89 MB of updates awaiting me, which I deferred while I worked on the TV part. Physical connection of the WinTV was trivial (power cord, USB to the PC, attach the cable, insert the CableCARD).  The installation screen lets you select an IR remote if you have one. I do, left over from Media Center, and selecting the standard Media Center remote worked ... for a while ... more about that below. The WinTV comes with its own remote, but I thought it would be easier to stick to the MCE remote (to which I'm used) rather than figure out how to get the WinTV remote to work.

For the video device, I selected the NVidia driver. There were a couple of drop down boxes to configure "TV-Out". I wasn't sure whether that was necessary, but I figured probably not; the prompt starts "If you would like to configure TV-Out". So I stuck with the default settings, which seems to have worked.

MythTV itself started, and suddenly the mouse was gone.  My first thought was "how the heck do I navigate", but the keyboard arrow and tab keys worked fine. I later discovered this is a design feature, not a bug. When you are in a MythTV window, there is no mouse cursor. MythTV expects you to navigate via the remote. I wish I'd seen that somewhere before I launched into the installation, but no harm done. The remote worked fine to advance, retreat, select and cancel. At least it worked for a while (more to come).

In the video setup menu, I clicked the hi-def test button. It downloaded a 70+MB HD movie clip and played it successfully in the TV ... other than a lack of sound. The setup wizard theoretically allowed me to configure sound. I chose ALSA, but no joy. So I tried various other ALSA settings in the list (specifically those that mentioned NVidia), along with clicking the rescan button, and had no luck.

After a bit of searching, I exited MythTV, opened a terminal, and ran aplay -L, which showed me default:NVidia as a recognized sound device. That's what I'd hoped for, so I ran sound-test -Ddefault:NVidia -c 2 -t sine and heard tones in both of the TV's built-in speakers. (Sidebar: without the -t sine argument, you get "pink noise", which to me sounds like a bad connection.)

I then went back to the sound configuration screen in the front-end, and lo and behold the choice had changed, on its own, to ALSA:dmix:CARD=NVidia, DEV=0, and sound was working in MythTV. Maybe I forgot to try that one, or maybe my tests in the terminal somehow made the device more visible (?).

To configure the video source, I followed these instructions with minimal difficulty. I've had an account with Schedules Direct for a while, so my channel lineup was already configured. The one hiccup was that clicking Fetch channels from listing source repeatedly failed to do anything, until I realized that the CableCARD was not firmly seated in the receiver slot. (Paul slaps himself a few times.)

Pairing the device required a call to Comcast, in which I needed to give them three pieces of data: the card's serial number; a host ID, and a device (data) ID. The serial number was on the receipt I got from Comcast, but where to get the other two things? The back-end settings have a menu for Capture Card, in which I selected HDHomeRun Prime for each of the two tuners, and was given addresses for them and an IP address (on my home network, so a nonroutable address). This turns out not to be what Comcast wants. When you install the WinTV in Windows 7, the information is magically provided to you, but where would I find it in Mythbuntu? After a bit of searching, I indirectly stumbled on the answer. That IP address in the Capture Card screen was for a web server built into the WinTV. I opened that in a browser and it handed me the necessary information, including the serial number, on a silver platter. I called Comcast and in fairly short order had the card authorized (although they warned me it could take 45 minutes for the card to download all the channel information it needed).

Somewhere in the middle of this process I turned off the PC and went out to dinner. When I returned and booted the PC, the IR remote no longer worked! That's happened a second time as well. When I first observed this, I wasted considerable time searching for the source of the problem, playing with various remotes, and looking in the wrong places for where I could reconfigure it. (System > Control Center > Infrared is where I select the remote.) The lsusb command, run in a terminal, failed to show the remote being attached. As it turns out, unplugging the receiver's USB cable and then plugging it back in fixes the problem. I think I ran across some tweaks one can make in system files to eliminate the need to do that, and I will definitely research that tomorrow. I can't picture having to reseat the remote cable every time I wake the computer.

I have not yet tried to record anything, nor to import my Windows recordings, so there will probably be a follow-up post. Meanwhile, there are two pressing issues. One is fixing that bug with the IR remote. The other is to figure out why the first channel in my cable lineup (which happens to be ABC) is showing programming dubbed in Spanish (?!). All the other channels coming through the WinTV tuner are in English, and the one that is dubbed when viewed through the tuner is in English when viewed through the cable box.

## Thursday, May 17, 2012

### I'm Retired - This Blog Is Not

I'm not big on personal posts in this blog (other than the occasional rant ... which probably says something about my personality).  Today I'll make an exception.  I've retired from Michigan State University after 33 years on the faculty, in the Department of Management (and 39 years on campus -- I did my graduate work here, in mathematics and statistics).

Yesterday was my first official day of retirement. (I say "official" because college faculty begin the retirement process the day after we get tenure and accelerate it the day after we make full professor.) When I went online, I discovered that my OR "peeps" had created a blog to commemorate my newfound freedom. I've commented on every post there, but I want to use this space to thank collectively all the folks who took the time (and, in some cases, considerable research effort) to write entries.  Special thanks to Mary Leszczynski for organizing it, and apologies to anyone who is still working out the kinks after having their arm twisted by Bjarni.  (The blog you're reading came to be because Bjarni twisted my arm at an INFORMS meeting until I caved -- and that was after I'd had roughly 15 years of martial arts practice!) Poring over the blog was a real treat for me.

I'm a bit of an outlier in the OR community (probably in many ways, but I'll cop to this one). Coming out of my doctoral program, which was in "pure" math and not OR, I was hired into a management science position in our business school. Counting me, we had three MS faculty, and one of those was a statistician. In the years that followed, as I was getting my footing in MS/OR (largely self-taught), the statistician retired, the other MS professor migrated to supply chain management, we killed off our MS and OR degree programs, and ultimately we killed off most of our quant methods classes. So I became an increasingly vestigial organ, and my contact with OR was through journals, INFORMS meetings, and to a large degree through sci.op-research (now tottering on its last legs) and the various web-based forums that followed it. The name of this blog stems from the fact that, for about a decade or so, my department has consisted of organizational behavior (OB) and strategy faculty, and me. Toward the end I was teaching introductory org behavior classes, which was the universe's version of a flashing neon sign pointing toward the exit.

I've met several of the people who posted to my retirement blog face-to-face on multiple occasions, always at an INFORMS meeting (or a video chat). I've met a few once (at INFORMS), and there are a few that I've yet to have the pleasure of meeting. The common denominator is that I've "met" them all online, either in a Q&A forum such as OR-Exchange, from my commenting on their blogs, on Twitter, or some combination of the above.  (I've made numerous circle connections on Google+, but to date I haven't had the time to do much with it. Perhaps that will change now.)  Believe it or not, I also have one coauthor on a journal article whom I've never met. It started with my answering his question on sci.op-research, with some email follow-ups, and spun into a publication.

So thanks to all of you who've interacted with me online, and who I hope will continue to interact with me online. Retirement from my day job does not imply retirement from OR. I'll continue the occasional mathematical snark hunt, at my own pace. Without a university to pick up the tab, I suppose I'll have to get a newspaper route to pay for at least one INFORMS conference per year. One way or another, I'll be around. To quote those great philosophers The Monkees, "... [I] don't have time to get restless, there's always something new ... Any time, or anywhere, just look over your [virtual] shoulder, guess who'll be standing there ..." (lyrics, sample)

I'll get back to serious business (?) with the next post.

## Wednesday, May 2, 2012

### Indicator Implies Relation

This is a follow-up to an earlier post on logical indicators in mathematical programming models. A common occurrence is to use a binary variable $y$ to turn a relation constraint (involving variables $x$) on or off.  Let $\sim$ denote any of the relations $=,\le,\ge$.  Without loss of generality, by moving all terms to the left side, we can write a generic relation involving $x$ as $f(x)\sim 0$ where $f()$ is an arbitrary function (linear if your model is to be a mixed integer linear program). To proceed, we will need to know a priori upper and lower bounds ($U$ and $L$ respectively) for $f(x)$, so that $L\le f(x) \le U \quad \forall x.$ Note that, in general, $L < 0 < U$ will hold, although we require neither $L < 0$ nor $0 < U$. If $L \ge 0$, then $f(x)\ge 0$ is automatic and needs no constraint.  Similarly $U \le 0$ guarantees $f(x) \le 0$ without additional constraints.

Let's start with the case where we want to say that $y=1 \implies f(x)\sim 0.$ If $\sim$ is $\ge$, we accomplish this with $f(x) \ge L(1-y)\qquad (1).$ Similarly, if $\sim$ is $\le$, we use $f(x) \le U(1-y)\qquad (2).$ For the case where $\sim$ is $=$, we combine (1) and (2).

I have excluded the case where $\sim$ is $>$ or $<$ because strict inequalities are anathema to mathematical programs: they cause the feasible region not to be closed.   That ties in to the next scenario: what if  $y = 1 \Leftrightarrow f(x)\sim 0$is the relation we want (i.e., we want equivalence rather then implication)? This can be broken down into two implications: \begin{eqnarray*}y=1 & \implies & f(x)\sim0\\ y=0 & \implies & f(x)\nsim0.\end{eqnarray*}
The difficulty is that $\nsim$ is either $>$, $>$ or $\neq$, all of which cause the feasible region not to be closed. So we will have to compromise. For the case where $\sim$ is $\ge$, combine (1) with $f(x)\le Uy.$With that combination, $y=1\implies f(x)\ge 0$ and $y=0\implies f(x)\le 0$, leaving the possibility that $f(x)=0$ for either value of $y$. Similarly, if $\sim$ is $\le$, combine (2) with $f(x)\ge Ly,$ so that $y=1\implies f(x)\le 0$ and $y=0\implies f(x)\ge 0$, again with ambiguity if $f(x)=0$. Sadly, there is no way to impose $y=1\Leftrightarrow f(x)=0$ when $f(x)$ takes values in a continuum.

As a parting note, $y=1\Leftrightarrow f(x)\sim 0$ can be modeled accurately for any relation (including equality and strict inequality) if $f(x)$ is known to be integer-valued.  In that case, $f(x) \gt 0$ equates to $f(x)\ge 1$, $f(x) \lt 0$ equates to $f(x)\le -1$, and $f(x)\neq 0$ is the disjunction of the two previous cases.