Sunday, March 13, 2016

Growing Censorship

I've been paying attention to things. Things you see one day, and they've changed the next.
YouTube music videos that have bad language are replaced with muted versions. And it's not just the F word, it's the word drugs. Popular culture being sanitized, "sucks" being deemed a swear, and not like Kid Rocks words of wisdom "suck my dick" but the widespread general usage, "that sucks". Honestly, today there was an article on WIRED titled, "Dancing in Shackles: Today your Adblock is taking a stand against censorship," and the article made no sense, WIRED blocks content from users using Adblock. Ransoming content for actual money, or forcing ads on the reader that are likely to be the source of the majority of viruses on the net. Censorship of public domain videos, which are becoming clickfarms instead. And no, Amnesty International has no anti-censorship focus going on, you'd have to be a detective to figure out what WIRED is talking about, as far as I can tell Amnesty is collecting donations to promote general human rights, like sexual reproductive freedom, freeing political prisoners and stopping police brutality. If you click on their google ad all you get is a donation form. As for Adblock, it's still blocking ads for now, so for the moment the user still has the power to censor content. It's a never ending struggle though, other people want to decide what you will, can, or must watch.

Saturday, November 9, 2013

Swale Burial

I guess the labor participation rate is down to 33% or something like that. I thought I had a line on something, but I guess I'm still part of the majority. I don't like the idea of being on too many lists, whenever I need to deal with the government it makes me nervous. Signed up for healthcare because my old state run system was closed for Obama. It worked second try, then they sent me a new DSHS identification card unsolicited, after signing me up for the renamed free state plan, but sending me no health card.  I'm guessing that they'll transfer records over from the old system eventually. Honestly, I get by, I just need my diabetes meds, and a checkup once in a while. Everyone who was paying attention knows they made a bunch of places dig nice drainage swales in the last decades, I'd hate to think they were just getting ready to have the mass graves all dug ahead of time for their death panels. I don't hate the president, Kristallnacht should never happen again. No one should censor the internet, the TEA party shouldn't be harassed by the IRS, businesses shouldn't be extorted and taken over by the government, and most of all people shouldn't have to start dying. Millions of people are being dumped from their health care plans, many of those plans were keeping chronically ill people alive. The insurance companies called these people "bad apples", they were losing money on them, but they were required to pay out, now they can drop the plans because of the president. The new state plan is "apple", that's not a good sign.

Friday, February 15, 2013

Driving Costs

The average American driver drives something like 15,000 miles in a year. That represents at least 250 hours of driving (based on an average speed of 60 miles per hour). The average car has a range of around 300 miles, so that 15,000 miles represents 50 trips to the pump, which at 5 minutes per fill up would be a little longer than 4 hours. So overall the average commuter is spending the equivalent of about 31 eight hour days driving every year... a full months worth.

The average plug-in hybrid driver probably only needs gas 10 times a year or so, or 50 minutes at gas stations in a year. However, they need to plug the car in, which might take a minute or so, and unplug it before they leave, which could take another minute, so over the course of a year there's 12 hours of plugging in and out. There's some experimental "park over" chargers that  might help eliminate that, if you take the time to install that... in both your garage floor and in your car. And there is the time for having the plug-in charger installed, though that will no doubt be done by someone else.

So time wise it's about 254 hours for a gas car, and 263 hours for a plug-in electric hybrid car. So it costs 9 hours more, or 3.5% more time to plug-in. The average hourly wage is something like $19.50, though it fluctuates, so overall driving time represents a loss of productivity of around $5,000 per person. $175 more if you drive a plug-in hybrid.

The workforce participation rate is something like 65%, so this $5000 per person represents about $1.17 Trillion in lost productivity. If all workers switch to plug-in hybrids (this isn't likely), the productivity lost will increase to $1.2 Trillion. There's that 3.5% again... so $35 Billion more lost since GDP is something like $15 Trillion that would be only a 0.25% decrease in the GDP. All based on a few minutes plugging in every day.

Friday, January 18, 2013

Large Files (some understandings)

Haskell tries to memoize everything at top level. That is, it tries to store the results in memory. So if you have some function that is supposed to be processing for a single line in a file ProcessLine :: Handle -> IO() then what happens is that if that code prints something that depends on the input, that is it depends on some content in the file you are opening, then it will evaluate the action. Otherwise it just stores the action to execute later. With a large file that might mean that every call to a ProcessLine function is just storing more into memory. More worryingly, it breaks specified action order sometimes, calling file actions after the file is closed. So essentially Haskell's handling of imperative programming order is somewhat broken, which makes sense, that part of the language is the part that the gurus don't like, so they write their code as pure functions, that part of the code remains untested in places, or they just think it's what should be.

The solution then is just to go ahead and fit all IO into one monolithic call that fits into memory, and write things in pure code like ProcessFile::IO() and ProcessLine :: String -> String and then just map a whole file lazily. In general, since ProcessFile is returned as a single action at the top level, using hGetContents will end up not being all stored in memory unprocessed. There's still some limits here, because ProcessLine might get memoized, and there's no method that I've found yet to just say not to do that.

Tuesday, May 1, 2012

Large Files

It's been a while. I'm looking for a good understanding of the memory leaking in GHC haskell. In general things that should be compiled in a simple manner tend to start turning into unevaluated chunks of stuff until some value is needed. That's great, lazy is handy sometimes, but sometimes it's just bad. The compiler should be making smarter choices about optimizing, there should be some sort of option to let it know you want to minimize memory usage anyway. As it is it always optimizes for speed, or code size or something. That leads to refactoring code in the hope of making it all behave better, one liners turn into massive libraries and weeks trying to understand how someone else managed to make something they think works, when a lot of time it's really experimental. There are dozens of versions of libraries about dealing with long files, almost all aren't tested, none seem to have any ease in using them. Reading values and processing something from a file should be easy, just sequence it all one chunk or line at a time, it shouldn't always try to force huge memory usage. This is the sort of thing that makes people say haskell is a toy language.

Saturday, August 20, 2011

Picnic



I went to a picnic at a park today.


that's me on the left... my nephew is on the right


There was lots of people there from my sister-in-laws family... that's my sister in law on the left, and my mother on the right.

The guy with my sister-in-law is Ned, the patriarch, he's 93.

Tuesday, February 9, 2010

Killer Cars

Toyota gas pedals: vroom...splat!
Prius brake computers: vroom...splat!
Volvo gas pumps: drip, drip...kaboom!

I wish that car companies weren't in such a hurry to add new features, and that government would stop being so strict on emissions. I had a two door Sunbird in the 80's that got 45 MPG and was sporty, I'm fairly sure the EC had been removed, but it ran clean. I'm sure a Prius isn't getting much better than 50 MPG, probably because of emissions laws. I've heard that a lightweight diesel car with manual transmission and good aerodynamics can get around 100 MPG if you drive it right.

It's the KISS thing, why spend billions redesigning something that already worked fine? Especially if the new one isn't really all that much better.

Wednesday, November 11, 2009

Penny

Is it just me, or does the new back of the penny look like Lincoln taking a dump?

Thursday, August 27, 2009

Politics, Death, and the End of Free Speech

For anyone that has been following American politics lately it can be overwhelming. There are more minor scandals than any average person has time to hear about, much less do anything about. I've come to the conclusion that it's the political version of a document dump. If you are unfamiliar with the term "document dump", it's a tactic used by big company lawyers when they are forced to provide some document, then they'll bury it in entire rooms full of mostly unrelated documents for the opposing lawyers. It's one of those loopholes in the law that most people don't care about, since everyone hates lawyers anyway. Whatever it is that the politicians are up to, it probably is major. For one thing Obama seems to have no intention of stopping warrantless wiretapping, or ending the war, the sort of things that typical Democrat voters really expected. Instead DoJ keeps up their appeals, and Striker gets re-deployed. You might think that the health care reform is where the effort is going, but most representatives haven't taken the time to read it, and Obama doesn't seem to care that his speaches about health care aren't anything like what is in the bill. They don't care that the cancer survival rates in places with universal care are 25% lower, they want control, and power. And more than anything, they want to control the media, with the media they can get re-elected, and get revenge on political opponents. Unfortunately for us the internet is part of what politicians consider the media, I'm sure it'll be a target.

Saturday, July 25, 2009

Haskell Variables

The Haskell community seems to have an aversion to anything imperative. IMO this has led to a fair amount of confusion, in particular about variables. A majority of people that learn Haskell are at least somewhat familiar with imperative languages, and almost all other languages rely heavily on mutable variables. When asking about variables the Haskell beginner is usually referred to let/in or where, but those are definition conveniences, not variables.

So one of the things that happens is heavier reliance on recursion, the values passed to the function can change like a variable, but they're still parameters. Which leads to encapsulating values in a state monad, and then passing the monadic values around.

What is a monad? That is where most people get very confused. Mathematically a monad is different than how it is implemented in Haskell! In Haskell a monad is really just a data type pointer. So you have something like IO Integer and it's a pointer to an Integer. Unfortunately the IO monad has no good constructor, you need to use IOArray, IORef, TVar or some other monad to create a variable. For now let's stick to using IORef since it's intended for this.

module Main where

import Data.IORef

main = do
-- a new variable called var
var <- newIORef (1::Integer)

-- the contents of var
a <- readIORef var

-- add one to var
modifyIORef var (+1)

-- the contents of var
b <- readIORef var

-- set var to 3
writeIORef var 3

-- the contents of var
c <- readIORef var

putStrLn $ show a
putStrLn $ show b
putStrLn $ show c

This is how variables are done in Haskell, with the following caveat: in general IORef isn't thread safe. So you might rather use something like:

module Variables (Variable, newVar, setVar, getVar, modVar, showVar) where

import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM

type Variable a = TVar a

-- initialize a new variable
newVar :: a -> IO (Variable a)
newVar value = atomically $ newTVar value

-- get the value of a variable
getVar :: Variable a -> IO a
getVar pntr = atomically $ do
value <- readTVar pntr
return value

-- set the value of a variable
setVar :: Variable a -> a -> IO a
setVar pntr value = atomically $ do
writeTVar pntr value
return value

-- apply a function to a variable
modVar :: Variable a -> (a -> a) -> IO a
modVar pntr fn = atomically $ do
value1 <- readTVar pntr
let value2 = fn value1
writeTVar pntr value2
return value2

-- a show function for a variable (for GHCI)
showVar :: (Show a) => Variable a -> IO ()
showVar pntr = do
value <- atomically $ readTVar pntr
putStrLn $ show value

This is thread safe on top of TVar. Variables.hs
So using this we'd have:

module Main where

import Variables

main = do
-- a new variable called var
var <- newVar (1::Integer)

-- the contents of var
a <- getVar var

-- add one to var
modVar var (+1)

-- the contents of var
b <- getVar var

-- set var to 3
setVar var 3

-- the contents of var
c <- getVar var

putStrLn $ show a
putStrLn $ show b
putStrLn $ show c

Which is almost the same as using IORef, but thread safe.

Tuesday, July 7, 2009

Ternary Trees

I ran across an interesting data structure, the ternary tree. Unlike binary trees, a ternary tree splits three ways at every branch. I went ahead and implemented it in Haskell. It should be able to store dictionary type data, or variable name-value look ups.

The basic idea is that a tree consists of branches, leafs, leafy branches, and stubs. Having a leafy branch allows for words to be prefixes of other words, as in the example.

Methods

newTrie a b :: (Ord a) => [a] b -> Trie a b

Create a tree from a single word [a] and associate a value b with it.

insert :: Ord a => [a] -> b -> Trie a b -> Trie a b

Insert a word [a] and a value b into a tree. Insert will return an error if the word already is part of the tree.

lookup :: Ord a => [a] -> Trie a b -> Maybe b

Find the value b associated with a word [a].

map :: (b -> c) -> Trie a b -> Trie a c

Apply a function (b -> c) to all the values b in a tree.

toList :: Ord a => Trie a b -> [([a],b)]

Convert a tree to a list of word-value pairs.

fromList :: Ord a => [([a],b)] -> Trie a b

Convert a list of word-value pairs to a tree.

instance (Binary a, Binary b) => Binary (Trie a b)

An instance of binary for efficient storage of trees. Example: encodeFile "filename" tree

Ternary.hs

Tuesday, May 26, 2009

Haskell Raytracer

Lately I've been working on writing a ray tracer in Haskell.

Mathematically it's fairly complicated. In general what you do is substitute the formula for a ray into the formula for an object, then find the roots of the resulting equation. So for example if you have a sphere equation:

where Sr is the sphere radius,
and the ray equation:


where P is the starting point, and D is the direction.
Then you substitute the ray equation for the XYZ portions:

and then simplify:

Which is in quadratic form, so there's possibly two solutions. Note that if is normalized then so it can be omitted from the calculation. Once you have the roots T then you just pick the smallest that is in front of the ray starting point by at least epsilon, and convert that to the XYZ point.
sphereIntersect :: Vector -> Double -> Ray -> Maybe Hit
sphereIntersect loc radius ray@(pnt,dir) =
let pl = pnt - loc
b = 2*((x dir)*(x pl) + (y dir)*(y pl) + (z dir)*(z pl))
c = (x pl)*(x pl) + (y pl)*(y pl) + (z pl)*(z pl) - radius*radius
q = filter (>=epsilon) $ quadRootsIgnoreA b c
in if (q == [])
then Nothing
else let ti = minimum q
iPoint = evaluateRay ray ti
iNorm = (iPoint-loc)/(toVector radius)
in Just (iPoint, iNorm)
Of course you can't end with just spheres, there's planes, boxes, triangles, flat discs, cones, etc.

Transforms are complex too. Say for example that you'd like to declare a right cone frustum as:
cone {basePnt, baseRad, topPnt, topRad}
then you need to rotate and scale the ray along with the cone so that you can test against a standardized cone where you know the formula for the surface:
So you end up with pairs of 4x4 matrices describing the transform and it's inverse. Interestingly, once you get a list of transforms to be applied (translate, rotate, scale) they can be composed together into a single transform by matrix multiplication.

The intention is to get this heavy matrix calculation to run once per object, and then use the result transform in testing multiple ray intersects. In Object Oriented languages like C++ this would be done at construction of the object, in Haskell I'd like to partially apply an intersect function, and then use the resulting function on a ray... so: objectFn :: Ray -> Maybe Hit
All that is to be tested and implemented still.

Currently I'm working on torus, a torus-ray intersect results in a quartic equation:
So that requires a good quartic solver...

Thursday, February 26, 2009

TomTom sued by Microsoft

The whole patent field has really gone around the bend. That any of the eight patents named in the Microsoft v. TomTom lawsuit were ever granted is legal insanity. Patents on: installing a computer in a car, installing wireless network support in a car, detecting when devices are plugged in to a computer, giving automated driving directions, panning a virtual map from a viewpoint, using flash memory, using both short and long file names. If you are counting that brings us to seven, the last one is a copy of the file name patent; that's right, it's just the same patent with a different number. None of these things are inventions in any real sense.
This is the sort of thing that has driven the economy into the second great depression. If the legal system continues to extort money in this manner then civilization may collapse.

Wednesday, February 4, 2009

Vista

The main computer here went kaput with a poof of smoke, so I took the opportunity to go without for the first time in years. There's always something on the internet that is entertaining in some manner, and I found myself replacing it with low quality TV shows. Eventually I ran out of fresh TV shows from the DVR and became startlingly bored. Then it became a great battle of procrastinators, who would give in and go buy a computer first? In the end I gave in first, using a birthday "gift" as an excuse, but I'm not fooling anyone, I'll be the one to use the new computer most.

Thus began the Vista woes, the Lexmark 3-in-1 printer isn't at all supported in Vista, and Lexmark basically is thumbing it's nose at customers, you can't get a Linux driver for it, you can't get a Vista driver, it might as well be a paperweight. Then re-installing programs has come up with dozens of paranoia firewall dialogs for each install. More startling, it's actually stalled the processor a few times... it's an AMD 1.8g quad core, so far I can't see much performance improvement from the old 1.8g Athlon. Thank goodness for backups, but all the registry is different, so it's password and number hunt week.

Tuesday, December 30, 2008

Plastic Welder

I got a plastic stick welder for Christmas. Essentially it's a heat gun with a small tip and a knob on the base to control the temperature of the air. After messing about with the different tips and burning some paint off of a steel pipe, I remembered that some iron forges use a heater for the air before it goes to the blast furnace. So I took two tin cans, one large and one a bit smaller and poked a hole in the side of the big can, and found a short section of 3/8" iron pipe that the welder nozzle fit into. Two lumps of charcoal in the bottom and a few pop cans smashed into the small tin can, the fire lit itself from the welder heat, and quickly heated to cherry red and melted the aluminum into a few tablespoons of slag. Then it burnt a hole into the bottom can opposite the air inlet and jumped to white hot for about 10 seconds as the last of the charcoal vaporized. The tin from the bottom can had melted and stuck to the rocks underneath. This is much to small to be of real use, it's difficult to fit the scrap into such a small crucible.

Sunday, November 9, 2008

Vectorizing



It kept bugging me that my Voronoi code didn't return anything but an image to double check, so I figured a way to go ahead and make it output SVG format paths. I also added some routines to help further simplify the paths, though the output still seems a bit rough. And it was a good thing to check my results, because the simple lengthening of segments somehow resulted in gaps in the path, the sort of thing that would ruin a circuit board. For now I just commented that part out and substituted code that checks if a line is trending in a direction, and then double checked against the error (measured as the sum of the distances from the proposed line to the pixels that would be removed).

I suppose that using Haskell for this might seem like an odd choice, but I'm more familiar with it than Python. The SVG image in this post should show up fine in Firefox. If your browser has trouble with it I'm sure you can Google around an get SVGs to display.
Vornoi.hs

Monday, October 27, 2008

Voronoi

After seeing Forrest Higgs working on using Voronoi isolates (a version of a Voronoi diagram that starts with lines instead of points) I was inspired to write a similar program which turned out well. The basic algorithm is to expand pixels around a color coded line until it meets another color. If a pixel is neighboring more than one color it gets painted black, rinse and repeat until there's nothing white left.

It was a bit of a struggle to get PNG images edited in Haskell, but eventually I realized that pixbufGetPixels isn't really returning an array, it's returning an array typed pointer to a pixBuf. This makes sense in a practical memory usage way, but it isn't what I expected from the context.

After that I vectorized the edges, that took quite a bit of thought. First line segments were created between the centers of adjacent black pixels, then segments were created from the center of black pixels to any corner of the black pixel where there was a color change between neighboring pixels, and lastly segments between differing colors. This left a bunch of empty sets, and repeated segments, which were filtered out. That resulted in about 4400 segments for this test image. The next step is to lengthen vectors that are near each other in the same directions. That reduced the number of segments for this test to about 3700, it probably could be much fewer if I hadn't limited the angles (0, 45, 90, and 135) or if the underlying lines were horizontal, vertical, and perfectly diagonal.

For now I can't go much farther without hardware to test on...

Voronoi.hs

Sunday, September 28, 2008

X Axis

The X axis is taking shape, I used an H shaped layout for the carriage, with drywall screws and skate bearings. There is no spring tensioner, the placement of the bearings press slightly against the rails, and there is enough give in the bed to fit it in without any play. This was accomplished by using washers as spacers between the end of the cross piece. With the two screws, after getting close to the right number of washers, the exact alignment is done by tightening or loosening the screws a small amount, this results in the end piece twisting, with a bit of finesse eventually it ends up being exactly right. The vertical alignment is simple by comparison, just use a single screw on the other end and tighten it, it should be no problem to force all four bearing wheels onto the track with the wood friction keeping the joint tight.


I also trimmed some plastic from the bed near the end to make clearance for the motor to be mounted to a threaded rod. There is a small tendency of the carriage to ride up out of it's slot, but when the rod is attached that will act to keep it from riding up. The profile of the rail should not matter much. The same setup should work fine with metal rod, pipe, angle iron, etc. Any profile where you have a straight inner surface, and a straight top surface.

Monday, September 8, 2008

Boxer Fan


I found a fan that looks a lot like a computer fan, but it's 110V and bigger. It was seized, so I removed the center from the bearings by persuading it with a hammer and a set. That released the blades and rotor. I cleaned away all the corrosion with emery paper, and sprayed it well with WD40. The bearings were still fine, so after pressing it back together the blades spun freely. I soldered a power cord to it and it runs OK; it's not too loud. I also rubber banded a 45 Gallon garbage bag to it to get an idea of the airflow, it filled the bag in five or six seconds, so it's probably about 60 cubic feet per minute.

Tuesday, September 2, 2008

Cooking with gas


I melted some more HDPE, this time I did it in the garage on a gasoline burner. I wrapped the plastic in aluminum foil to keep it from sticking to the pan. Then I squashed it flat between two pans and left some heavy chain on it while it cooled. I ended up with a 1/4" x 8" cookie of plastic sheet, it's mostly flat, and the foil is well stuck to it. I'm not sure what I'll use it for. Mostly I've just been cleaning and storing stuff from the pile. My second computer won't boot any more, it sat too long, or it needs a battery, and the power supply was always extra noisy, it locks part way through boot up usually. I wonder if this was related to the ethernet problem I had last month, even though that computer is off most the time. All the time now I guess, maybe I'll get a couple new power supplies, and try one in that. I need another computer for the garage anyways, so I can do the RepRap stuff there.