![]() |
|
Spaces home The Light Cone (Brian's ...ProfileFriendsFiles | ![]() |
|
|
July 02 How to Type Matrices in Word 2007Insert -> Equation
then, type \matrix ( a & b @ c & d )
The ampersand separates elements on a line, the at-sign separates lines. Type as much as you want, it all gets laid out beautifully. Nest the whole thing inside brackets of various kinds. Very similar to LaTeX. I've found that most of the LaTeX backslash commands work in an intuitive way in Word 2007. Lovely! June 24 Tuval-Cain == Vulcan ?Tuval-Cain, in the seventh generation after Adam according to the book of Genesis: וְצִלָּה גַם-הִוא, יָלְדָה אֶת-תּוּבַל קַיִן--לֹטֵשׁ, כָּל-חֹרֵשׁ נְחֹשֶׁת וּבַרְזֶל "And Tzilla also gave birth to TUVAL-CAIN, forger of every sharp implement in brass and iron..." (4:22). His name and profession are much too similar to those of the forge-master of Romano-Greek mythology, Vulcan, to be coincidence. However, I've been unable to find any research on this. June 23 How About a Boxcar?A Boxcar Filter is a gadget that runs (or maps) a function of four arguments over a rectangular grid of points. A rectangular grid is a data structure where each point has a pair of integer indices, i and j, say, and i runs from, say, 1, through M and j runs from 1 through N. The data structure is best viewed as a function from i and j to some value, which can be anything. Even better, let it be a list of lists, in the usual Mathematica way. The function of four arguments that the Boxcar filter maps over the grid expects four, nearest-neighbor points:
h[p1, p2, p3, p4],
p1=grid[i, j], p2=[i+1, j], p3[i, j+1], p4[i+1, j+1] The Boxcar filter mapper, then, must intelligently skip the last row and column. Enjoy:
fRows[opOf2Rows_,{a_,b_,c___}]:= fRows[_,{a_}]:={};
gCols[op4_,{a_,b_,c___},{d_,e_,f___}]:= gCols[_,{a_},{d_}]:={};
boxCar[op4_,grid_]:= Here's an application that draws criss-crosses in each box of a grid. Ampersand converts the previous expression into a function (a lambda expression), in which #1, #2, ... denote positional arguments. Thus, {Line[{#1,#4}],Line[{#2,#3}]}& is a function of four arguments:
crissCross[grid_]:=boxCar[{Line[{#1,#4}],Line[{#2,#3}]}&,grid] The problem with MaxIs, of course, the recursive call on line 2:
Max[{x_, xs___}] := x if x > Max[{xs}];
While mathematically correct, it will cause recalculation over the tail, xs, for each element of the list, transforming a trivial linear algorithm into a quadratic. The solution, as usual, is to introduce another formal argument:
Max[l_] := MaxHelper[l, -Infinity];
MaxHelper[{}, a] := a;
MaxHelper[{x_, xs___}, a] := MaxHelper[{xs}, x] if x > a;
MaxHelper[{x_, xs___}, a] := MaxHelper[{xs}, a] otherwise;
June 15 Functional FunnyThe following is a correct implementation of Max over a list in a pattern-matching language like Mathematica. It has an amusing fault. Can you spot it? Max[{}] := -Infinity; Max[{x_, xs___}] := x if x > Max[{xs}]; Max[{x_, xs___}] := Max[{xs}] otherwise; April 16 An AnswerFrom my consultations with C# insiders, looks like ~"loop variables are special"~ meaning that the compiler won't make private copies for "enclosured" or "outer" variables. The issue is the difference between "instantiating" variables and "initializing" them in the C# spec http://msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx (see "Outer Variables" in section 7.14.4 around page 206). Proof? The following works as expected ... introducing the non-"special" variable j causes the compiler to make copies of it for each closure. static void Main(string[] args) { for (var i = 0; i < 40; i++) { var j = i; new Thread(() => { Thread.Sleep(1); Console.Write("{0} ", j); }).Start(); } Console.WriteLine(); } "Special" is one of those words, like "simple," that should cause concern. "Special" means ~"varies from the normal way of things."~ Some people think it's a euphemism for "good"; in my experience, special cases lead to nasty surprises, like this one. "Simple" is subjective. To some people it means "flattened, explicit, without ambiguity." To others it means "short or small, even if abstracted, implicit, or ambiguous." I've seen grown engineers argue for hours that their solution is "simpler" than the other guy's, with the two of them meaning exactly the opposite by the term. April 15 Fun with Threads and Closures(empirical programming -- try something, see what happens, guess what the compilers are doing) Here is a broken program: class Program { static void Main(string[] args) { for (var i = 0; i < 40; i++) { new Thread(() => { Thread.Sleep(1); Console.Write("{0} ", i); }).Start(); } Console.WriteLine(); } } It's broken because the inner lambda expression refers to the variable i, which can have any old value between 0 and 40 INCLUSIVE. Using i as an array index would probably generate a bounds exception. The lambda expression will likely see many repetitions of the same value of i, yadda yadda. It's junk. Now press the magic "refactor / extract method" button, and get a program that works (after a suitable warning that semantics might change -- but, of course, that's exactly what we want: the semantics to change from INCORRECT to CORRECT): class Program { static void Main(string[] args) { for (var i = 0; i < 40; i++) { g(i); } Console.WriteLine(); } private static void g(int i) { new Thread(() => { Thread.Sleep(1); Console.Write("{0} ", i); }).Start(); } } The lambda expression now produces a permutation of the integers between 0 and 39, and that's just fine. But, I'm scared because I thought the stack variables, in this case, the int i argument of g, would go away by the time the lambda expression were called, so the compiler is probably making nice copies of them somewhere. No, and I'm just lucky? Boxing? Not sure what's going on, but rather not look a gift horse in the mouth, as they say. January 03 Take This TestIf you're a programmer or mathematician, you might like this test. This is not a trick question. Which of the following two alternatives, A or B, is the SIMPLER: A: 1 + 2 * 3 B: <binaryExpression> After some number of responses have accumulated or some time has gone by, I'll post my thoughts and experiences around this question. I have asked this question to dozens of people. I reiterate, it is not a trick question, so please give an honest answer. Metathesis -- Permuting LettersHere's another nice one: גזרה, root גזר, referring to a decree or edict, usually negative. "And then" התרגז, root רגז, get angry. First the evil decree, then get angry. Makes sense. Cycling the last letter to the front of a root is just one form of metathesis. There are many others. הזדקן, "he got old," is a euphonic metathesis plus a substitution, from the formal reflexive הת+זקן, which is unpronounceable, but most certainly is a formation of the second-person pronoun אתה "you" plus the verb זקן "old." First, the metathesis of ת with ז -> הזתקן , then the softening of ת to ד to give הזדקן. There are six permutations of every root. Maybe I'll do a nice search for all of those. Complicating my procedure (greatly) is the fact that Hebrew letters are overloaded with respect to etymological origins. ח stands for two letters (written separately in Arabic as حhha and خ kha), ז for two (ز za and ظ zdha in Arabic), ש for two (Hebrew retaining dots often even in unvoweled text), ג for two (Arabic keeping only one, the ج jim), ד and ת each has historical soft forms retained in Arabic, בכפ each have modern soft forms, ע has two (ع and غ still in Arabic), and the ever-loving צ stands for three ancient letters (ص, ض, and another one), plus samekh ס seems out of place, perhaps retained in Greek as Ξ. This means that a permutation might be related to a considerable number of other roots, some of which are spelled exactly the same. What a mess, eh? Despite their being just 22 Hebrew letters, there are about 34 different potentially meaningful sounds to account for. Some of them, like ב and בּ are probably just euphonic differences and don't harbor etymological distinctions. Others like ד and דּ are usually completely different letters.
December 14 More Shoresh PairsTurns out my last computer search had a bug that overlooked some pairs containing the letter "Shin." I redid the search and found 99 more pairs. The new file is in my folder עברית, which you should be able to see above. I deleted the old file.
The bug had to do with not properly matching Shin (dot on right-hand side) with the dotless variation of the letter. I only picked up Sin (dot on the left-hand side), which is the more rare variation of the letter. Evaluation is NOT Universal (probably)I deleted my blog entry from a few days ago (and reminded myself to use the Brady Bill in the future). I asserted that eager evaluation alone sufficed to simulate a Turing machine, but my proof had a flaw, and when I fixed the flaw, I had just reinvented the IO Monad, which does not depend on evaluation order, so my proof is trash. I no longer think evaluation alone accounts for any side-effecting computation, but I'm not sure one way or the other. December 13 XNA from F# and C#I've gotten one of the first XNA 1.0 tutorials going in F# called from a tiny C# stub. I got the basic approach for the 3-way integration from grammarjack's blog. The tutorial is documented HERE; it tests for collisions in 2D between falling "anvils" and a mobile "person," reminiscent of the old Space Invaders control model. The C# stub is a Visual Studio Express project, as are all official XNA applications. Its source code follows: namespace MyGame { static class Program { static void Main(string[] args) { File1.FSharpCalledFromCSharp(); // File1 refers to File1.fs, the F# DLL } } } My F# version is a VERY straightforward translation of the original C# code of the tutorial -- maybe "transliteration" is a better word. It’s side-effecting EVERYWHERE because that’s object-oriented programming. Construction starts with the usual field initialization followed by a “then” clause that makes some subordinate objects, followed by an “Initialize” callback that does even more setup after graphics has been partly set up, followed by “LoadGraphicsContent” which does even MORE setup even LATER. The main loop has an Update entry point and a Draw entry point which communicate by (you guessed it) side-effected fields. It may be interesting in the future to do a "topological inversion refactoring" of this code structure to sequence the side effects more monadically. I preserved another deficiency of the original: various rectangle and vector types seem schizophrenic about floats, ints, or float32s. I just inserted whatever coercions necessary to get it to run. Perhaps later it would be interesting to consolidate and reconcile all that noise. Despite these issues, the code is not hard to read to my eyes anyway, and is a little prettier than the C# version since I managed to sweep some counted loops into maps and filters. Build a DLL in Visual Studio 2008 with F# added in, and run the program from the C# executable after adding a reference to the F# DLL. Here's the F# code: #light #I @"c:\Program Files\Microsoft XNA\XNA Game Studio Express\v1.0\References\Windows\x86" #r "Microsoft.Xna.Framework.dll" #r "Microsoft.Xna.Framework.Game.dll" open Collections open Compatibility open Idioms open Microsoft.Xna.Framework open Microsoft.Xna.Framework.Audio open Microsoft.Xna.Framework.Content open Microsoft.Xna.Framework.Graphics open Microsoft.Xna.Framework.Input open Microsoft.Xna.Framework.Storage open System open System.IO type MyGame = class inherit Game as base val mutable graphics : GraphicsDeviceManager val mutable content : ContentManager val mutable personTexture : Texture2D val mutable blockTexture : Texture2D val mutable spriteBatch : SpriteBatch val mutable personPosition : Vector2 val PersonMoveSpeed : float32 val mutable blockPositions : Vector2 list val BlockSpawnProb : float val BlockFallSpeed : int val random : Random val mutable personHit : bool (* set in "Update", tested in "Draw" *) val mutable safeBounds : Rectangle (* would like this to be constant, but must be set in "Initialize" after graphics set up *) val SafeAreaPortion : float new () as this = { graphics = null content = null personTexture = null blockTexture = null spriteBatch = null personPosition = Vector2(0.0f) PersonMoveSpeed = 5.0f blockPositions = [] BlockSpawnProb = 0.02 BlockFallSpeed = 2 random = Random () personHit = false safeBounds = Rectangle(0,0,0,0) SafeAreaPortion = 0.05 } then this.graphics <- new GraphicsDeviceManager(this) this.content <- new ContentManager(this.Services) this.graphics.PreferredBackBufferWidth <- 853 this.graphics.PreferredBackBufferHeight <- 480 override this.Initialize() = base.Initialize () let vp = this.graphics.GraphicsDevice.Viewport this.safeBounds <- Rectangle (int (float vp.Width * this.SafeAreaPortion), int (float vp.Height * this.SafeAreaPortion), int (float vp.Width * (1.0 - 2.0 * this.SafeAreaPortion)), int (float vp.Height * (1.0 - 2.0 * this.SafeAreaPortion))) this.personPosition.X <- float32 (this.safeBounds.Width - this.personTexture.Width) / 2.0f this.personPosition.Y <- float32 (this.safeBounds.Height - this.personTexture.Height) override this.LoadGraphicsContent (loadAllContent : bool) = if loadAllContent then this.blockTexture <- this.content.Load<Texture2D>("Content/Block") this.personTexture <- this.content.Load<Texture2D>("Content/Person") this.spriteBatch <- new SpriteBatch(this.graphics.GraphicsDevice) override this.UnloadGraphicsContent (unloadAllContent : bool) = if unloadAllContent then this.content.Unload () override this.Draw(gameTime) = let gd = this.graphics.GraphicsDevice gd.Clear(if this.personHit then Color.Orange else Color.CornflowerBlue) this.spriteBatch.Begin() this.spriteBatch.Draw(this.personTexture, this.personPosition, Color.White) List.iter (fun (v : Vector2) -> this.spriteBatch.Draw(this.blockTexture, v, Color.White)) this.blockPositions this.spriteBatch.End() base.Draw (gameTime) override this.Update(gameTime) = let kb = Keyboard.GetState() let gp = GamePad.GetState(PlayerIndex.One) if (gp.Buttons.Back = ButtonState.Pressed || kb.IsKeyDown(Keys.Escape)) then this.Exit() if (kb.IsKeyDown(Keys.Left) || gp.DPad.Left = ButtonState.Pressed) then this.personPosition.X <- this.personPosition.X - this.PersonMoveSpeed if (kb.IsKeyDown(Keys.Right) || gp.DPad.Right = ButtonState.Pressed) then this.personPosition.X <- this.personPosition.X + this.PersonMoveSpeed this.personPosition.X <- MathHelper.Clamp (this.personPosition.X, float32 this.safeBounds.Left, float32 this.safeBounds.Right - float32 this.personTexture.Width) if this.random.NextDouble () < this.BlockSpawnProb then let x = this.random.NextDouble() * float (this.Window.ClientBounds.Width - this.blockTexture.Width) this.blockPositions <- Vector2 (float32 x, - float32 this.blockTexture.Height) :: this.blockPositions this.blockPositions <- this.blockPositions.Map (fun v -> Vector2 (v.X, v.Y + float32 this.BlockFallSpeed)) let personRectangle = Rectangle (int this.personPosition.X, int this.personPosition.Y, this.personTexture.Width, this.personTexture.Height) this.personHit <- List.exists (fun (v : Vector2) -> personRectangle.Intersects (Rectangle (int v.X, int v.Y, this.blockTexture.Width, this.blockTexture.Height))) this.blockPositions this.blockPositions <- this.blockPositions.Filter (fun v -> v.Y <= float32 this.Window.ClientBounds.Height) end (*class*) let FSharpCalledFromCSharp () = let game = new MyGame() game.Run() December 09 Shoresh Pairs in HebrewI've noticed plausible "and then" relationships in the meanings of pairs of three-letter roots, or "shoreshim," in Hebrew. Start with one root, say לקח, and move the last letter to the front, to get another root, חלק. The first root, לקח, means "to take," and the second root, חלק, means "to divide, split, apportion." It's plausible to say "take, and then divide," as with spoils of war. Could there be other pairs of roots connected by the same kind of "consequence" relationship? Another case might be שכח then חשך, "forget" and then "darkness" (the middle letter, כ, changes only its written shape to ך, when it becomes the last letter). For another, consider קשב and בקש, "pay attention" then "request." Could this be a general kind of relationship? Just coincidence? Or real? If so, by design? Ancient? Or newer? If so, by mere drift of meanings? Or reassignment by language authorities? Is there a similar kind of relationship in other Semitic languages, all of which share the three-letter-root system? These are the obvious hypotheses. Many Arabic roots are very close in meaning to Hebrew roots, and it would be interesting to investigate them. Aramaic, Amharic, and Ancient Egyptian all have three-letter-root systems that might be interesting to explore. Background: In all these languages, the great majority of all kinds of words relate directly to a three-letter root, easy to identify knowing just a little grammar, and obviously related in meaning to all the words. For instance, using English letters for a moment, the root KTB generates KATAV, "he wrote," or "a journalist;" MIKHTAV, "a correspondence or letter;" MIKHTAVAH, "a writing desk;" KATVAH, "a magazine or newspaper article;" KTAV, "handwriting;" KITUV, "caption;" KTUBAH, "marriage contract;" KTOVET, "mailing address;" and several others. The root in Arabic is identical, and many of the derived words are very similar. It is clear that this is a very ancient root. As with all the other languages in its family, the entire Hebrew language flows out from applying patterns of vowels and helper consonants to three-letter roots. In the rest of this post, I show a few of these "and then" pairs I found by hand, then the results of a computer search, which turned up a few hundred, some of them very interesting, others very far-fetched. First, quick fundamentals. Write Hebrew from right-to-left. The last letter is the leftmost. Moving a letter to the front means moving it all the way to the right. There are 22 letters in the Hebrew alphabet, and 5 of them have "flourishes" at the ends of words. These 5 letters look different when moved to the front, and the new last letter, which is the old middle letter, looks different in the new root if it's one of these 5. Here are the 5 "funny" ones:
Referring to this table, see that לחץ becomes צלח: "push, or press" and then "succeed." Here is the entire alphabet, just the normal forms. To appreciate the rest of this post, you don't need to know them by heart, you just need to see that I move a letter from the back (the left) to the front (the right), sometimes changing its shape.
Here are the pairs I found by hand, just reading various Hebrew texts:
In the uploaded file are almost four hundred more that I found by computer search. I haven't looked at all of these or evaluated them for plausibility, but this does seem like an interesting thing to "mine." (In the public uploaded files section, called "ShoreshPairs.xls". October 06 Digression on FunctionsA friend of mine asked for some clarity concerning Currying, Partial Evluation, Functions that return functions (higher-order functions) and such things. I've added "Digression On Functions" to my Public Folder above. Take a look and feel free to comment. October 04 New version of SICM in MMAAdded some instrumentation so we may watch the solution process (essentially Exercise 1.5, but this was a real workout, requiring me to understand deep details of evaluation order in MMA, rather painfully, but worth it).
Also greatly improved the mathematical preliminaries based on trying to explain the thing to Erik Meijer. Nothing like explaining something to force one to clarify it.
All in the "Classical Mechanics" folder above. October 02 My SICM uploadsIn a public folder called "Classical Mechanics," you will find a PDF file and a Mathematica notebook (*.nb file) containing my first chicken-scratchings about SICM. Get a free notebook reader from http://www.wolfram.com/products/player/download.cgi . October 01 SICM in MathematicaFor some time, I've wanted to work through SICM (Structure and Interpretation of Classical Mechanics -- http://mitpress.mit.edu/SICM/). The book assumes MIT Scheme and scmutils, both free software packages.
Deepest learning comes from working through a whole topic, top to bottom, so I decided not to use their software stack, but to create a fresh software stack using their prose as a guide. I also decided to implement my work in Mathematica, which has lots of mathematical knowledge and visualization capabilities built in. That is ordinary stuff no one should want to reinvent. I've just started with this, but the results are already promising. I've managed to reproduce their numerical results exactly, plus I have some extra symbolic capabilities. I'm going to figure out how to post my results here. |
|
|