second experiment in screen recording

July 17, 2017 math and physics play No comments , , , , ,

Here’s a second attempt at recording a blackboard style screen recording:

 

To handle the screen transitions, equivalent to clearing my small blackboard, I switched to using a black background and just moved the text as I filled things up.  This worked much better.  I still drew with mischief, and recorded with OBS, but then did a small post production edit in iMovie to remove a little bit of dead air and to edit out one particularly bad flub.

This talk covers the product of two vectors, defines the dot and wedge products, and shows how the 3D wedge product is related to the cross product.  I recorded some additional discussion of duality that I left out of this video, which was long enough without it.

experiment in screen recording: An introduction to Geometric Algebra.

July 14, 2017 math and physics play No comments , , ,

I’ve been curious for a while what it would take to create lesson style screen recordings, and finally got around to trying one myself:

 

This is an introduction to Geometric (Clifford) algebra.  I briefly outline a geometrical interpretation of various products of unit vectors, rules for reducing products of unit vectors, and the axioms that justify those rules.

I made this recording using the OBS screen recorder, using a Mac, drawing with a Wacom tablet and using Mischief as my drawing application.  I have to find a way to do the screen clearing transitions more smoothly, as there are sizable dead time delays while I do the ‘File -> Import -> Recent -> …  ; Don’t save’ sequence in mischief to reload.  I also um and ah more than I like, something I think I could avoid if presenting this to a real live person.

quantum spin dreams

July 13, 2017 Incoherent ramblings No comments , , , , ,

I woke up this morning with the perception that I had been dreaming about designing trinary computers and topics related to quantum spin for a large chunk of the night.   Why I would have been dreaming about this is not at all obvious.  I didn’t go to bed thinking about any scientific or computer engineering topics.

In my dream it seemed natural to use spin-1 quantum states to build a trinary clock signal for the microprocessor.  That basically means that the clock signal would be optical, since photons can have spin 1, 0 or -1.  However, what would it even mean to have a spin synchronized clock signal.  This would be a state that could be measured at any point on the microprocessor that has a time varying spin, but measurement of that spin would not alter the spin states of all the other photons in the clock signal?  If measurement of the signal at one point on the chip cannot perturb the overall clock signal, then there must be a large number of particles involved.  Also how could you prepare a stream of photons that you could measure the spin and know before hand what the observed spin state should be at any given point in time?  Is the spin state of any given photon not random when measured?

So, perhaps the clock signal is a complex entangled many-photon state?  Is there a mechanism to produce an entangled state for which the measured state at any point in time would be cyclic?  I haven’t even studied any aspects of quantum information theory, other than knowing that entangled states exist.  Perhaps questions like these are already well understood?

I also dreamed of a large clear glass-like window pane, in which all the spin-1 particles had their spins synchronized.  I guess this is a similar, but simpler version of the microchip spin synchronized clock signal, just not varying with time.  In my dream I wondered what the optical properties of “glass” would be if there was a large degree of spin synchronization.  Now, does glass even have any spin-1 particles?  Perhaps the window pane in my dream was built of some other material, like plastic or Star Trek like transparent aluminium.  Even supposing that it was possible to synchronize the spins in a large number of particles, the optical effects of doing so are not clear to me.  We do calculations of reflection and transparency in electromagnetism, but there the underlying nature of the transparency is treated as a black box, having to do with the electric and magnetic permittivity.  I understand transparency to be a bulk solid state quantum statistical mechanics phenomena, but  don’t really know enough to be able to, say, compute the optical properties of a given crystal lattice of some arbitrary material.  Understanding that has been a goal since I was a kid (perhaps since I saw “The voyage home” with my grandparents as a kid), but I haven’t gotten that far in my studies yet, or if I have, I haven’t put all the pieces together mentally.

In a metal, like aluminum, there would be many free electrons.  Perhaps the spin of those half-integer spin particles could be synchronized.  What would be the optical properties if that was done in a large sheet of material?  In stat-mech we did the calculations that related spin to magnetic moment, so there would surely be magnetic properties to such a spin synchronized surface.  It is kind of interesting that we have two so very different mechanisms for magnetism, one due to quantum half integer spin, and the other due to relativistic effects of observing electrons in motion.  There are surely some subtle ways these are related in quantum field theory, but I don’t know much of that topic either.

This purpose of this dream sequence really seems to be pointing out to me how little I know, in the big picture sense, about how electrodynamics and quantum mechanics fit together.

patriotism, and worship of war, state and country

July 12, 2017 Incoherent ramblings No comments , , ,

I was reading the Gulag Archipelago, by Solzhenitsyn last night before bed, and now find myself up in the middle of the night, not able to sleep.  At first it seemed rather mysterious why I’d be wide awake with anti-patriotism and anti-war thoughts rolling around in my head so strongly, but I finally connected those thoughts with my bedtime reading.

This book reads like a real life version of 1984, starting off with stories of arrests, interrogations and searches.  Perhaps it hits so closely to home since it is so easy to see so many other aspects of 1984 playing out for real in our society around us.  It is probably not a good bedtime reading choice if I want to be able to sleep through the night.

As I lay tossing and turning at ~3am, definitively not sleeping, I had four specific memories rolling around in my head.  All were anti-state and anti-patriotism memories.

You might get the impression that Canadians are anti-war.  Part of this is because “our” participation in war is covert, and not advertised.  If “we” happen to be playing the bombing for dollars in game Kosovo or Syria, it isn’t because there is an explicit declared war, but instead because we are part of NATO “peace-keeping” (hello Orwell!) forces.  Canadian participation in the wars of our belligerent neighbour is expected.  Like the US, we aren’t creating terrorism, we are fighting it!

Canadians aren’t indoctrinated in the believe in the goodness of war as heavily as our US counterparts, but there are some lines that can’t be crossed without getting severe emotional reactions.  I challenge anybody to disrespect the religious Oh Canada or Remembrance day ceremonies, or the sanctity of the belief that Canadians were saving lives by participating in the world wars.

In my own head I had come to the internal conclusion that Oh Canada is nothing but a patriotism indoctrination tool.  The “we stand on guard for thee” words in the song scream exactly this.  I remember being a kid, standing proudly in various public school indoctrination centres, feeling proud to be Canadian, proudly listening to the “with glowing hearts” line.  However, like so many other national anthems, the Canadian anthem appears to have been rolled out in force as a war propaganda action, in our case for WWII, the “good war”.  People are still of age to have plenty of relatives that fought in WWII and aren’t mentally prepared for second guessing absolute confidence that Canadian participation in that war was beneficial.  It is a lot easier to relish the memory of loved grandfathers than to admit that their grandfathers were unfortunate pawns in the games of the power brokers that profit from war.  Canadian participation in WWII is viewed as a shallow “we saved the world from Hitler” point of view.  There are many aspects of this war that you are not allowed to think about.  You are supposed to think of the battles that Canadians helped save the day fighting.  You are not supposed to think of all the civilians that were killed and displaced.  You are not supposed to think about all the German civilians that were killed in bombing raids, and that the British were playing that city bombing game with as much relish as the Germans.  You are allowed to think about Hitler’s concentration camps, but not allowed to think about Allied cooperation with Stalin, who killed many times more of his own people than Hitler managed to kill in camps or active war.  How can a war be good when it aids and facilitates one of the worst murderers in history?

Thoughts of these sorts are hard to enunciate on the spot if you should decide to not participate in the indoctrination game of standing to attention during Oh Canada, or not standing still during a Remembrance day ceremony.  Memories of two specific instances of running the social experiment of not participating in these observances were rolling through my head.  One was at a public school when the national anthem interrupted a talk with the principle that was much more important seeming to me than the anthem (the insanity of how multiplication was being taught to Karl, our current household public school victim).  The other was returning a book at the public library when my conditioning to stand silent during the remembrance day ceremony way playing.  Should you try this social experiment, I can tell you what will happen.  You will get looks of shock and horror, and what easily appears to be pure hatred.  This is from peace loving Canadians.  I was not brave enough to play this game when the US national anthem played at my brother’s recent graduation ceremony.  I can imagine coming out of that auditorium with injuries had I decided to disrespect that particular religious ceremony.  It was both amusing and horrifying to observe the feelings of adoration as all those Americans stood enraptured with their hands on their hearts as their national anthem played.  I am thankful that it was standing room only at Devin’s graduation.  Would I have been tempted to sit during the US national anthem had I not already been standing?  I didn’t have a convenient and well articulated response for sitting at hand for such a social experiment.  I suppose that I could have claimed to be a practising Jehovah’s witness.  It is ironic that one of the only responses that may have been acceptable, like the anthem itself, would have also been religious.

I think there is perhaps value to actively not playing the Oh Canada game or the remembrance day game.  Doing that may be enough to get some people to realize exactly how conditioned their behaviour is.  At the same time, it makes people angry, which is counter productive, because people cannot reason when they are angry.   Instead perhaps consider for your self just how angry you would get if some insolent snot like me didn’t stand for attention during the anthem or walked around during a remembrance day ceremony, when we all know that you are supposed to stand still quietly.  Can you honestly say that you wouldn’t get angry to observe that?  If you did get angry, consider your reasons for that anger.  Does the fact that fact that you were forced to comply with this religious ceremony again and again and again in school have anything to do with your conditioned response?

Good patriots stand for attention during the national anthem.  Good patriots do not question the goodness of war.  Good patriots fight without considering they are being manipulated to fight the battles of others and line the pocketbooks of the power brokers that love war.  What could be wrong with encouraging patriotism?

My dad was thoroughly anti-state, and a lot of that rubbed off on me.  I think that I learned my disrespect for Remembrance day from him.  I didn’t understand it when I was a kid.  He’d been a refugee himself.  He’d lost his original home and country, his biological father, and much of his family and roots.  He’d ended up with an abusive and drunkard of a step father.   My dad was Estonian, a country that was a desirable territory in its day, having been repeatedly occupied by both German and Russian forces as they passed through it in their insane fight.  I heard many stories from my insane step grandfather about Estonian guerrilla tactics against both the invading Germans and the invading Russians.  They seemed to support the good-war indoctrination that I was receiving at school, but they didn’t work on my dad.  It was very confusing when I was kid that he didn’t respect the sanctity of remembrance day having had such personal involvement in WWII, but I think I understand some of the factors now.  Part of it is probably fairly simple.  Had there not been a world war to “fight Hitler”, the Estonians would have just had to fight the Germans in their home territory as they passed through to Russia.  Imagine that the only actions taken against the Germans were defensive, and that the Germans had to fight guerrilla tactics on all fronts in all directions from their invading epicenter.  That might have been a good war.  The real story is nothing of the sort, since fundamentally, the war was desired by the British and others, and there were hard fights on many fronts to get others involved in the game.

The other thoughts that were floating around in my head had to do with the religion of Trump in the USA.  In my youth, before I found Quantum Mechanics and Maxwells’ equations, my own religious indoctrination was that of Scientology.  Until recently, I thought of Scientologists, like my dad, as predominately anti-state, but have been disabused of that notion thoroughly by my recent visit to the US, where I discovered that there are a number of true believers in my family (both active Scientologists and also fellow childhood indoctrinees).  I guess it is true that Scientology is a multi-denominational religion.

I’ve dumped enough thoughts that I think I’ll try to go back to sleep now.  I will leave thinking through vague thoughts on Trumpism and Scientology to another day.

Building a new BBQ drip tray.

July 3, 2017 Incoherent ramblings No comments ,

My old BBQ drip tray was in really rough shape:

In exchange for coffees, the installer of our new energy efficient (and functional!) air conditioner gave me a nice new piece of sheet metal, so I’m traced out a new drip tray:

Here it is before any folds:

I don’t have a brake, nor access to a metal shop, but Sofia bought Lance a little vice a few Christmases ago, and I borrowed that:

I also found that a heavy ruler (one of the edges of my square), worked well to help with the bends

The very skinny bends were harder to do nicely, and I had to resort to some pliers to help coerce them into place, but the final result is pretty decent and a lot less porous:

It looks a bit out of place with all the rust in the remainder of the BBQ, but should help give the unit a few more years:

 

Unpacking a PL/I VSAM keyed write loop.

June 7, 2017 Mainframe No comments , , , , ,

I found myself faced with the task of understanding the effects of a PL/I WRITE loop that does the initial sequential load of a VSAM DATASET.  The block of code I was looking at had the following declarations:

     dcl IXUPD FILE UNBUFFERED KEYED env(vsam);
     dcl
        01 recArea,
            03 recPrefix,
                05 recID        PIC'(4)9' init (0),
                05 recKeyC      CHAR (4)  init (' '),
            03 recordData       CHAR (70) init (' ');

     dcl recIndx FIXED BIN(31) INITIAL(0);

     dcl keyListSize fixed bin(31) initial(10);
     dcl keyList(10) char(8);

As a C++ programmer, there are a few of oddities here:

  • Options for the FILE are specified at the file declaration point (or can be), not at the OPEN point.  They can also be specified at the OPEN point.  The designers of PL/I seem to have been guided by the general principle of “why have one way of doing something, when it can be done in an infinite variety of possible ways”.
  • There is a hybrid “structure & variable” declaration above.  recArea is like an object of an unnamed structure, containing nested parts (with lots of ugly COBOL like nesting specifications to show the depth of the various “structure” members).  It’s something like the following struct declaration (with c++11 default initializer specifiers):
    #include <stdio.h>
    
    int main() {
        struct {
            struct {
                char recID[4]{'0', '0', '0', '0'};
                char recKeyC[4]{' ', ' ', ' ', ' '};
            } recPrefix;
            char recordData[70]{ ' ', ' ', /* ... 70 spaces total */ };
        } recArea;
    
        printf( "recID: %.4s\n", recArea.recPrefix.recID );
        printf( "recKeyC: '%.4s'\n", recArea.recPrefix.recKeyC );
    
        return 0;
    }
    

    To PL/I’s credit, only ~45 years after the creation of PL/1 did C++ add a simple way of encoding default structure member initializers.

    We’ll see below that PL/I lets you access the inner members without any qualification if desired (i.e. recID == recArea.recPrefix.recId). The PL/I compiler writer is basically faced with the unenviable task of continually trying to guess what the programmer could have possibly meant.

  • The int32_t types have the annoying “mainframe”ism of being referred to as 31-bit integers (FIXED BIN(31)). Even if the high bit in pointers is ignored by the hardware (allowing the programmer to set 0x80000000 as a flag, for example for end of list in a list of pointers), that doesn’t mean that the registers aren’t fully 32-bit, nor does it mean that a 32-bit integer isn’t representable. I can’t for the life of me understand why a 32-bit integer variable should be declared as FIXED BINARY(31)?
  • The recID variable is declared with a PICTURE specification, as we also saw in COBOL code. PIC ‘9999’ (or PIC'(4)9′, for “short”), means that the character array will have four (EBCDIC) digits in it. I don’t quite understand this specification in this case, since the code (to follow) seems to put ‘RNNN’, where N is a digit in this field.

Here’s how the declarations above are used:

    
     keyList(1) = 'R001';
     keyList(2) = 'R002';
...
     OPEN FILE(IXUPD) OUTPUT;

     put skip list ('====== Write record to file by key.');
     do while (recIndx &lt; keyListSize);
        recIndx = recIndx + 1;
        recID = recIndx;
        recKeyC = 'Abcd';
        recordData = 'Data for ' || keyList(recIndx);
        write FILE(IXUPD) FROM(recArea) KEYFROM(keyList(recIndx));
     end;
     put skip list (recIndx, ' records is written to file by key.');

     CLOSE FILE(IXUPD);

My guess about what this ‘WRITE FROM(recArea)’ would do is to create records of the form:

0001AbcdData for R001
0002AbcdData for R002
0003AbcdData for R003
...

However, the VSAM DATASET (which was created with key offset 0, and key size 8), actually ends up with:

R001    Data for R001
R002    Data for R002
R003    Data for R003
...

Despite the fact that we are writing from recArea, which includes the recID and recKeyC fields (numeric and character respectively), only the non-key portion of the WRITE “data payload” ends up hitting the disk.

If that is the case, where do the spaces in the key-portion of the records come from? Again, the C programmer in me is interfering with my understanding. I look at:

dcl keyList(10) char(8);
keyList(1) = 'R001';

and think that keyList(1) = “R001\x00\x00\x00\x00”, but it must actually be space filled in PL/I! This seems to be confirmed emperically, based on the expected results for the test, but I can also see it in the debugger after manually relocating the 32-bit mainframe address:

(gdb) p keyLen
$1 = 8
(gdb) p /x aKey + 0x7ffbc4000000
$2 = 0x7ffbc5005740
(gdb) set target-charset EBCDIC-US
(gdb) p (char *)$2
$3 = 0x7ffbc5005740 "R001    R002    R003    R004    R005    R006    R007    R008    R009    R010    "

The final form of the records in the VSAM DATASET (mainframe for a file), is now fully understood. Note that the data disagrees with the PICTURE specification for the recID field in the recData variable declaration, but that’s okay, at least for this part of the program, since there is never any store to that field that is non-numeric. Would anything even have to have been written to recID or recKeyC … I suspect not? Once we have R00N in that part of the record what happens if we read it into recData with the numeric only PICTURE specification? Does that raise a PL/1 condition?

ps. Notice how the payload for the keyList array entries is nicely packed into memory. This is done in a very non-C like fashion with no requirement for an array of pointers and the corresponding cache hit loss those pointers create when accessing a big multilevel C array.

Still amused reading my PL/1 book: external storage.

May 28, 2017 Mainframe No comments , , , ,

The z/OS Enterprise PL/I, Language Reference is the primary reference I have been using for the PL/1 that I’ve had to learn, but it is too modern, and not nearly as fun as the 1970’s era “PL/I structured programming book” I’ve got:

 

I’m not sure what a disk pack is, but I presume it is a predecessor to the hard drive.

Edit: Art Kaufmann, who I worked with at IBM, knew what a disk pack was (picture above from wikipedia):

“Back in the day, disk drives used removable media called “disk packs.” These were stacks of disks (usually about 2′ across) on a spindle with a plastic cover. See the IBM 2311 and 2314 for examples of these drives. You’d open the drive, lower the pack into place, twist the handle and remove the cover, then close the drive. The big risk was getting dust in when the cover was off; that would cause a head crash. Then some nitwit operator would either put a different disk pack in that drive (ruining that pack) or move the bad pack to a new drive, crashing that one. Or both.”

 

 

 

 

LLVM IR Null pointer constants and function pointers. A wild goose chase after a bad assumption.

March 30, 2017 clang/llvm No comments , , , , , ,

With ELLCC, you can easily check out the LLVM IR for code like:

typedef void ( *f )( void );
void foo( void );

f bar() {
    return (f)foo;
}

That code is:

define nonnull void ()* @bar() local_unnamed_addr {
  ret void ()* @foo
}

declare void @foo()

I was trying to use @foo in a “struct” object, and was getting an error attempting this:

llvm/lib/IR/Constants.cpp:879:llvm::ConstantAggregate::ConstantAggregate(
 llvm::CompositeType*, llvm::Value::ValueTy, llvm::ArrayRef<llvm::Constant*>):
 Assertion `V[I]->getType() == T->getTypeAtIndex(I) &&
 "Initializer for composite element doesn't match!"' failed.

After adding:

fooFunc->dump();

where it shows the whole function body of foo(), I thought that’s where the error was coming from, and that I needed some other method to obtain just “@foo”, a global variable reference to the function, and not the function body itself.

The actual story is much simpler. Here the LLVM code to generate the IR for a foo() with this interface:

//------------
// void foo(){ }
//
auto vt = m_builder.getVoidTy();
auto voidFuncVoidType = FunctionType::get( vt, false /* varargs */ );

Function *fooFunc = Function::Create(
    voidFuncVoidType, Function::InternalLinkage, "foo",
    m_module );
BasicBlock *fooBB =
    BasicBlock::Create( m_context, "", fooFunc );
m_builder.SetInsertPoint( fooBB );
m_builder.CreateRetVoid();

My clue that the error is something else is that I am able to build a function that returns a foo function pointer:

//------------
// void(*)() bar() { return foo ; }
//
auto fpRetFuncType = FunctionType::get( voidFuncVoidType->getPointerTo(), false /* varargs */ );

Function *barFunc = Function::Create(
    fpRetFuncType, Function::ExternalLinkage, "bar",
    m_module );
BasicBlock *barBB =
    BasicBlock::Create( m_context, "", barFunc );
m_builder.SetInsertPoint( barBB );
m_builder.CreateRet( fooFunc );

The module at this point looks like:

define internal void @foo() {
   ret void
}

define void ()* @bar() {
   ret void ()* @foo
}

So why can I used fooFunc in a return statement, but don’t appear to be able to use it in a structure object? Here’s the code that created that structure type

//------------
//
// struct { int, void (*)(), char * }
auto i8t = m_builder.getInt8Ty();
auto i32t = m_builder.getInt32Ty();
std::vector<Type *> consStructMembers{
    i32t, voidFuncVoidType->getPointerTo(), i8t->getPointerTo()};
auto consStructType =
    StructType::create( m_context, consStructMembers, "" );

and my attempt to populate an object of this type:

//
// %struct { int, void (*)(), char * } = { 65535, foo, null };
//
auto consPriority = ConstantInt::get( i32t, 65535 );
auto consDataZero = ConstantInt::get( i8t->getPointerTo(), 0 );

std::vector<Constant *> v{consPriority, fooFunc, consDataZero};
Constant *g = ConstantStruct::get( consStructType, v );

The actual error was in the third struct member initialization, and had nothing to do with the function pointer value. In retrospect, this makes sense since llvm::Function is derived from llvm::Constant, so there shouldn’t logically be a mismatch there.

What actually fixed the error was simply:

auto consDataZero = ConstantPointerNull::get( i8t->getPointerTo() );

It appears that the numeric zero value isn’t the same thing as an LLVM ‘null’. With that corrected, my variable declaration is:

%"type 0x10ea0c0" { i32 65535, void ()* @foo, i8* null }

… so I should now be able to proceed with the actual task at hand.

COBOL code! Where’s the eyewash station?

March 20, 2017 Mainframe No comments , , , , , , ,

In code that I am writing for work, I’m calling into COBOL code from C, and in order to setup the parameters and interpret the results, I have to know a little bit about how variables are declared in COBOL. I got an explanation of a little bit of COBOL syntax today that takes some of the mystery away.

Here’s the equivalent of something like a declaration of compile time constant variables in COBOL, a hierarchical beast something akin to a structure:

004500 01  CONSTANT-VALUES.                                             ORIG_SRC
004600     02  AN-CONSTANT PIC X(5) VALUE "IC104".                      ORIG_SRC
004700     02  NUM-CONSTANT PIC 99V9999 VALUE 0.7654.                   ORIG_SRC

This is roughly the equivalent of the following pseudo-c++11:

struct
{
   char AN_CONSTANT[5]{'I','C','1','0','4'};
   struct {
      char digits1[2]{'0', '0'};
      char decimalpoint{ '.' };
      char digits2[4]{'7', '6', '5', '4'};
   } NUM_CONSTANT;
} ;

Some points:

  • The first 6 characters are source sequence numbers.  They aren’t line numbers like in BASIC (ie. you wouldn’t do a ‘goto 004500’), but were related to punch cards to make sure that out of sequence cards weren’t inserted into the card reader, or a card wasn’t fed into the reader by the operator by accident.
  • The ‘ORIG_SRC’ stuff in column 73+ are ignored.  These columns are also related to punch cards, as an additional card sequence number could be encoded in those locations.
  • The 01 indicates the first level of the ‘structure’.
  • The 02 means a second level.  I don’t know if the indenting of the 01, 02 is significant, but I suspect not.
  • PIC or PICTURE basically means the structure line is a variable and not the name of a new level.
  • A sequence of 9’s means that the variable takes numeric digits in those locations, whereas the V means that location is a period.
  • A sequence of X’s (or the X(5) here that means XXXXX), means that those characters can be alphanumeric.
  • There is no reference to ‘CONSTANT-VALUES’ when the variables are referenced.  That is like a namespace of some sort.
  • The level indicators 01, 02 are arbitrary, but have to be less than 77 (why that magic number? … who knows).  For example 05, 10 could have been used, so that another level could have been inserted in between without renumbering things.

The 01, 02 level indicators are also used for global variable declarations, also somewhat struct like:

004900 01  GRP-01.                                                      ORIG_SRC
005000     02  AN-FIELD PICTURE X(5).                                   ORIG_SRC
005100     02  NUM-DISPLAY PIC 99.                                      ORIG_SRC
005200     02  GRP-LEVEL.                                               ORIG_SRC
005300         03  A-FIELD PICTURE A(3).                                ORIG_SRC

This might be considered equivalent to:

struct
{
   char AN_FIELD[5];
   char NUM_DISPLAY[2];
   struct {
      char A_FIELD[3];
   } GRP_LEVEL;
} GRP_01;

Here:

  • A(3), equivalent to AAA, means the field can have ASCII values.
  • The name ‘GRP-LEVEL’ header for the 03 structure level is not referenced in the code.

It is also possible to declare a variable as binary, like so:

005400 77  ELEM-01 PIC  V9(4) COMPUTATIONAL.                            ORIG_SRC
  • Here 77 is a special magic level number, that really means what follows is a variable and not a “structure”.
  • The V here means an implied decimal place in the interpretation of the value.
  • The 9(4), equivalent to 9999, means the variable must be able to hold 4 numeric digits.
  • The COMPUTATIONAL means the underlying variable must be able to hold a value as big as 9999.  i.e. a short or unsigned short must be used, and not a char or unsigned char.

The final variable group in the code I was looking at was:

005500 01  GRP-02.                                                      ORIG_SRC
005600     02  GRP-03.                                                  ORIG_SRC
005700         03  NUM-ITEM PICTURE S99.                                ORIG_SRC
005800         03  EDITED-FIELD  PIC XXBX0X.                            ORIG_SRC

which is roughly equivalent to:

struct
{  
   struct {
      char NUM_ITEM[2];
      struct
      {
         char digits1[2];
         char blank1[1]{' '};
         char digits2[1];
         char zero1[1]{'0'};
         char digits3[1];
      } EDITED_FIELD;
   } GRP_03;
} GRP_02;         

Here

  • EDITED-FIELD includes fixed blank and zero markers (B, 0 respectively).  When a four character variable is copied into this field, only the characters in the non-blank and non-zero values are touched.
  • NUM-ITEM is a signed numeric value.  It’s representation is strange:

The signed representation is also char based, and uses what is referred to as an “over-punch” to encode the sign.  The normal (EBCDIC) encoding of a two digit variable 42 without a sign, would be:

‘4’, ‘2’ == 0xF4, 0xF2

when the S modifier is used in the PICTURE declaration, the F in the EDCDIC encoding range is changed to either C or D for unsigned and signed respectively.  That means the ‘4’, ‘2’ is encoded as:

0xF4, 0xC2

whereas the signed value “-42” is encoded as:

0xF4, 0xD2

The procedure prototype, specifically, what the parameters to the function are, are given in a ‘PROCEDURE DIVISION’ block, like so:

005900 PROCEDURE DIVISION USING GRP-01 ELEM-01 GRP-02. 

Here

  • The first 6 characters are still just punch card junk.
  • Three variables are passed to and from the function: GRP-01, ELEM-01, GRP-02.  These are, respectively, 10, 4, and 8 bytes respectively.
  • On the mainframe the COBOL function could be called with R1 something like:
struct parms {
    void * pointers[3];
    char ten[10];
    uint16_t h;
    char eight[8];
};

//...
struct parms p;

p.pointers[0] = &p.ten[0];
p.pointers[1] = &p.h;
p.pointers[2] = &p.eight | 0x80000000;

strncpy( p.ten, "XXXXX00ZZZ", 10 );
p.h = 0;
strncpy( p.eight, "99XXBX0X" );

setregister( R1, &p );

The 0x80000000 is the mainframe “31-bit” way of indicating the end of list. It relies on the fact that virtual memory addresses in 32-bit z/OS processes have only 31-bits of addressable space available, so you can hack one extra bit into a pointer to indicate end of list of pointers.

Suppose the program has statements like the following to populate its output fields

006400 MOVE AN-CONSTANT TO AN-FIELD. 
006500 ADD 25 TO NUM-DISPLAY. 
006600 MOVE "YES" TO A-FIELD. 
006700 MOVE NUM-CONSTANT TO ELEM-01. 
006800 MOVE NUM-DISPLAY TO NUM-ITEM. 
006900 MOVE "ABCD" TO EDITED-FIELD. 

The results of this are roughly:

strncpy( p.ten, "IC104", 5 ); // MOVE AN-CONSTANT TO AN-FIELD (GRP-01)
strcpy( p.ten + 5, "25", 2 ); // ADD 25 TO NUM-DISPLAY (GRP-01): since the initial value was "00"
strncpy( p.ten + 7, "YES", 3 ); // MOVE "YES" TO A-FIELD. 
p.h = 7654 // MOVE NUM-CONSTANT TO ELEM-01. 
strcpy( p.eight, "25", 2 ); // MOVE NUM-DISPLAY TO NUM-ITEM. 
strncpy( p.eight + 2, "AB C0D", 6 ); // MOVE "ABCD" TO EDITED-FIELD. 

It appears that the the assignment of NUM-CONSTANT, a number of the form 99.9999 to the numeric value ELEM-01 which is of the form .9999, just truncates any whole portion of the number.

Notes compilation for ECE1505, Convex Optimization

March 18, 2017 ece1505 No comments

I’ve now posted a notes compilation for the subset of the Convex Optimization (ECE1505H) course I was taking in the winter 2017 session.

This course was taught by Prof. S. Draper.

These convex optimization notes are incomplet, covering only the first 9 lectures. The unredacted notes include my solution to problem set 1 (149 pages, vs. 131 pages).

I initially enrolled on this optimization course because I needed a specific quota of ECE courses to satisfy the M.Eng graduation requirements, and the electromagnetics group wasn’t offering enough courses.  I remembered liking linear programming in high school, and always wanted to understand the rational for some of the assumptions that was based on that were never proven in class.  Specifically, I recall that it was stated, but not proved in that high school class, that the extreme values were always found at the vertices of the optimization region.  So, my thought was, I’ll have fun learning the basis for those assumptions, and also learn about optimization theory in general.

It turns out that optimization theory, at least as presented in this course, is very very dry.  It was an endless seeming sequence of definition and proof, with the end goal so far away that it was very difficult to see the big picture.  I worked through the a number of weeks of this particular course before I had enough and bailed.  Work is too fun right now to torture myself and spend the time on an academic course that I am not enjoying, so I dropped it and am back to full time work at LzLabs (from 80%) until the next session at UofT starts again.

The reason I enrolled on the M.Eng in the first place was to study material that I was interested in.  Ideally I would have done that in a part time physics grad context, but that was not available, so I found that the M.Eng allowed me to take an interesting (but constrained) mix of physics and engineering electromagnetism courses.  However, when I enrolled, the electromagnetism course selection was a lot better, and now unfortunately it is sparse and includes only courses that I’d already taken.  I don’t want the M.Eng degree paper badly enough to torture myself with a course that I’m not actually interested in.

I now actually have a plan to satisfy both the degree requirements and my interests (using a project “course”).  That will involve independent study on Geometric Algebra applications to engineering electromagnetism.  I am irked that I have to pay a part time engineering program fee next year to self study, but it does seem worthwhile to come out of the M.Eng study with an actual degree as a side effect, so I am going to go ahead and do it anyways.