This doesn't achieve the goal I started with, but following Dieter's example:
Code:
W001 LBL W
W002 INPUT R // starting register #
W003 INPUT M // # lines
W004 INPUT N // # columns
W005 ABS
W006 IP
W007 STO N
W008 1E3
W009 /
W010 ENTER
W011 SGN
W012 +
W013 STO T // temporary
W014 RCL M
W015 ABS
W016 IP
W017 STO M
W018 1E3
W019 /
W020 ENTER
W021 SGN
W022 +
W023 STO L // line counter
W024 RCL M
W025 RCLx N
W026 RCL R
W027 STO I // address pointer
W028 +
W029 STO J // memory curtain
W030 STO (J) // store non-zero value
W031 RCL T
W032 STO S // stack (column) counter
W033 [IP(L),IP(S)]
W034 STO E
W035 ALL
W036 INPUT E // display E? [line, stack]
W037 STO(I)
W038 ISG I
W039 ENTER
W040 ISG S
W041 GTO W033
W042 ISG L
W043 GTO W031
W044 EQN R+(R+(MxN)-1)/1E3+M/1E5 // control number bbb.eeell
W045 RTN
Example:
Code:
3 1 4 1
A = 5 9 2 6 starting with register R11
5 3 5 8
control number = 11.02203 the first register is R11 , the last one is R22 and there are 3 lines. Store this in A to identify matrix A.
Could alternately enter the input in the stack instead (I'm not a fan of input queries):
REGY [M,N]
REGX R
A proposed test for scalar:
Code:
W037 EQN (E*[1,0])*(E*[0,1])
W038 X=0?
W039 GTO XXX
W040 RCL E
W041 STO (I)
.
.
.
If E=scalar the equation should always be 0; if E=vector (in terms of matrix position, i.e. never [0,0]) it should be a positive number <>0.
(02-28-2015 09:53 PM)mbrethen Wrote: [ -> ]This doesn't achieve the goal I started with
I still do not understand what this goal is or was. Could you provide an example?
(02-28-2015 09:53 PM)mbrethen Wrote: [ -> ]A proposed test for scalar:
...
If E=scalar the equation should always be 0; if E=vector (in terms of matrix position, i.e. never [0,0]) it should be a positive number <>0.
Fine. In the meantime I found a similar solution I was about to post.
Dieter
My understanding if the goal is that we want to enter an undefined number of values and at some point signal that the table is complete. The expectation is that when the user has entered the last value and is asked for the next one, he would simply press Enter and then a flag should indicate that nothing was entered which means -> end of data entry.
Is that correct?
If that is the case, I would suggest KIS!
Don't use INPUT, just a simple STOP and then GTO in the data entry loop.
Then when data entry is complete, just have a second LBL B ready and expect the user to press XEC B when data entry is complete instead of entering a value and pressing R/S.
So the scenario would be:
Code:
XEQ A
Enter value R/S
Enter value R/S
Enter value R/S
Enter value R/S
...
XEQ B
You're done.
Code sample:
Code:
A001 LBL A
A002 0.999
A003 STO I
A004 RCL I
A005 IP // shows index of next expected value (line above shows previous value)
A006 STOP
A007 STO(I)
A008 ISG I
A009 GTO A004
A010 SF 10
A011 EQN MAX 999
A012 RTN
B001 LBL B
etc...
(03-01-2015 04:13 PM)Tugdual Wrote: [ -> ]My understanding if the goal is that we want to enter an undefined number of values and at some point signal that the table is complete. The expectation is that when the user has entered the last value and is asked for the next one, he would simply press Enter and then a flag should indicate that nothing was entered which means -> end of data entry.
Is that correct?
Yes, all of the examples I've seen were limited to square matrices or vectors. Other than the user specifying a starting register and entering the element values, the program should do the rest.
(03-01-2015 07:48 PM)mbrethen Wrote: [ -> ]Yes, all of the examples I've seen were limited to square matrices or vectors. Other than the user specifying a starting register and entering the element values, the program should do the rest.
OK, so the user enters, say, 12 values, and then simlpy presses R/S to indicate all elements have been entered (and stored). How does the program know if these 12 values define a 3x4 or 4x3 or 2x6 or 6x2 matrix?
Please forgive me if I once again have to ask for an example. What does the user enter, which keys are pressed, and what is the program supposed to do with this input. Please give a complete example with every single key pressed.
Dieter
(03-01-2015 08:59 PM)Dieter Wrote: [ -> ]OK, so the user enters, say, 12 values, and then simlpy presses R/S to indicate all elements have been entered (and stored). How does the program know if these 12 values define a 3x4 or 4x3 or 2x6 or 6x2 matrix?
The user puts the starting register on the stack. Executing the "matrix writer" program, it queries each element, column by column. When the user presses R/S the first time, that signals the end of first column and there are "m" rows. It then queries additional columns. When the user presses R/S a second time, that signals the end of the nth column and the program "learns" "m" rows and "n" columns. It finishes by placing a "control number" on the stack: bbb.eeerr
where
bbb = beginning register
eee = end register
rr = number of rows
This control number will be used by other programs that operate on the matrix.
Quote:Please forgive me if I once again have to ask for an example. What does the user enter, which keys are pressed, and what is the program supposed to do with this input. Please give a complete example with every single key pressed.
In the example posted earlier:
11 XEQ "W" the HP-35 displays A? [1,1]
3 R/S A? [2,1]
5 R/S A? [3,1]
5 R/S A? [4,1] first column is stored
R/S A? [1,2] now, the HP-35 knows the matrix has 3 rows
(continues until)
1 R/S A? [2,4]
6 R/S A? [3,4]
8 R/S A? [1,5] all the elements are stored
R/S
REGX = 11.02203 first register is R11 , last is R22 and there are 3 rows.
Sample code to query column:
Code:
W001 LBL W
W002 SF 0
W003 STO I
W004 1.001
W005 STO* I
W006 ENTER
W007 FP
W008 STO J
W009 1E3
W010 STO* J
W011 RDN
W012 X<> J
W013 [IP(LASTx),IP(REGX)]
W014 STO A
W015 RDN
W016 INPUT A
W017 R^
W018 R^
W019 (A*[1,0])*(A*[0,1])
W020 X<>0?
W021 GTO W049
W022 X<> A
W023 STO(I)
W024 CLX
W025 1E-5
W026 FS? 0
W027 GTO W029
W028 CLX
W029 STO+ I
W030 SGN
W031 STO+ I
W032 +
W033 FS? 0
W034 GTO W006
W035 RCL I
It's not complete, I need to add the logic to cycle through each column and then put the control number in the stack.
(03-02-2015 02:26 AM)mbrethen Wrote: [ -> ]The user puts the starting register on the stack. Executing the "matrix writer" program, it queries each element, column by column. When the user presses R/S the first time, that signals the end of first column and there are "m" rows. It then queries additional columns. When the user presses R/S a second time, that signals the end of the nth column and the program "learns" "m" rows and "n" columns. It finishes by placing a "control number" on the stack: bbb.eeerr
where
bbb = beginning register
eee = end register
rr = number of rows
This control number will be used by other programs that operate on the matrix.
OK, now I get what you want. The following code should be able to do this. Try it and see what you get.
Code:
W001 LBL W
W002 ABS
W003 IP
W004 STO B // base register#
W005 0,9 // add 0,9 so that ISG increments, but always tests true
W006 +
W007 STO I // start with entered base register
W008 1
W009 +
W010 STO J // j=i+1 is used to prestore a non-zero value
W011 1,9
W012 STO D // d = 1,mmm. If m is not yet known, assume m is very large (e.g. 900)
W013 SF 1 // set flag 1 to indicate that no empty entry occured yet
W014 1,9
W015 STO C // column index
W016 RCL D
W017 STO R // row index
W018 EQN [IP(R), IP(C)]
W019 STO A
W020 CLSTK
W021 ALL
W022 INPUT A
W023 ENTER // another way of checking whether
W024 ABS // x is scalar or vector
W025 LASTx
W026 [1,0]
W027 x
W028 ABS
W029 x≠y? // is x a vector (i.e. no entry was made?)
W030 GTO W041 // then determine #rows resp. #columns
W031 1
W032 STO(J) // otherwise store non-zero value in variable (i+1)
W033 R↑
W034 STO(I) // store input in variable (i)
W035 ISG I // increment both i
W036 ISG J // and j
W037 ISG R // increment row index
W038 GTO W018 // get next row
W039 ISG C // increment column index
W040 GTO W016 // get next column
W041 FS? 1 // first occurence of R/S without entry?
W042 GTO W063 // then determine m = #rows
W043 RCL C // otherwise matrix is complete
W044 IP
W045 1
W046 -
W047 STO N // determine n = #columns
W048 VIEW N
W049 PSE
W050 RCL M
W051 1E5
W052 ÷
W053 RCL M
W054 RCLx N
W055 RCL+ B
W056 1
W057 -
W058 1E3
W059 ÷
W060 +
W061 RCL+ B // compute control number bbb.eeemm
W062 RTN // and quit
W063 CF 1 // reset "first empty input" flag
W064 RCL R
W065 IP
W066 1
W067 -
W068 STO M // determine m = #rows
W069 1E3
W070 ÷
W071 1
W072 +
W073 STO D // compute 1,mmm
W074 VIEW M
W075 PSE
W076 ISG C // increment column index
W077 GTO W016 // get next column
However, I think this method of entering a matrix is not a good idea. After the number of rows is known, the user has to enter complete columns. What happens if he doesn't? For instance, if there are m=3 rows but the user quits in column 5 after entering just one value? Are the following elements A[5,2] and A[5,3] assumed zero? Should the program throw an error? This would require some additional code after W043.
That's why I would prefer the classic approach: simply have the user enter m and n.
Dieter
This performs most of the computations using just the stack. The A, I and T named variables are used for input, indirect register access and temporary storage, respectively. It is based on a program for the HP-41 by Jean-Marc Baillard. I have translated it for the HP-35s. In addition to the HP-41 Flag 22 issue, there were other parts of the code I had to work around: "sign" of zero results in 1 on the HP-41 (0 on the 35s) , ISG loop counter and STO arithmetic on the stack (e.g. STOx Y). As Dieter pointed out, the program isn't fail safe but I like the fact that it does all the bookkeeping for you.
Thanks to all who participated in this topic.
Code:
W001 LBL W
W002 SF 1 // set flag 1 to indicate first column
W003 ABS
W004 IP
W005 STO I // start with entered base register
W006 1.001
W007 STO* I
W008 ENTER
W009 FP
W010 1E3
W011 *
W012 EQN [IP(REGY),IP(REGX)]
W013 STO A
W014 R^
W015 R^
W016 ALL
W017 INPUT A // display A? [line, column]
W018 ABS // check if x is scalar or vector
W019 [1,0]
W020 RCL* A
W021 ABS
W022 X<>Y? // is x a vector?
W023 GTO W051 // next column
W024 RDN
W025 X<> A
W026 STO(I) // store input in register (i)
W027 CLX
W028 1E-5
W029 FS? 1
W030 GTO W032
W031 GTO W033
W032 STO+ I // increment # of rows
W033 SGN
W034 STO+ I // increment register#
W035 +
W036 FS? 1 // enter another element in the first column?
W037 GTO W008
W038 RCL I
W039 FP
W040 STO T
W041 ISG T
W042 IP // skipped if base register is zero
W043 X<> T
W044 REGY
W045 IP
W046 -
W047 X<0?
W048 GTO W058
W049 RDN
W050 GTO W008
W051 R^
W052 R^
W053 FS? 1 // first column is stored?
W054 GTO W056
W055 GTO W066 // all the elements are stored
W056 CF 1 // the next column indexes will be automatically incremented
W057 ENTER
W058 CLX
W059 1E-3
W060 +
W061 FP
W062 STO T
W063 ISG T
W064 X<> T
W065 GTO W008
W066 SGN // get the control number of the matrix
W067 +/-
W068 RCL+ I
W069 IP
W070 STO I
W071 LASTX
W072 FP
W073 1E3
W074 *
W075 FP
W076 STO+ I
W077 RDN
W078 LASTX
W079 IP
W080 RCL I
W081 1E3
W082 /
W083 +
W084 RTN
CK=6CA0
LN=302
Revision History
3/6/15 – Fixed an issue with the loop counter at line 42.
3/7/15 – Shortened the control # routine.
3/8/15 - Added line W025 so that absolute value isn't stored.
(03-06-2015 04:27 PM)mbrethen Wrote: [ -> ]This performs most of the computations using just the stack. The A, I and T named variables are used for input, indirect register access and temporary storage, respectively. It is based on a program for the HP-41 by Jean-Marc Baillard. I have translated it for the HP-35s. In addition to the HP-41 Flag 22 issue, there were other parts of the code I had to work around:
More or less direkt translations of programs for other platforms are not always the best idea. On the HP41 saving registers makes sense, because every unused data register can be used to store the matrix and/or is available for additional program memory. That's why using the stack is a good idea. On the 35s however, the direct variables A–Z are always allocated and completely independent from program memory. They also do not store the matrix which resides in the indirect variables.
BTW: you should change your step W023 to RCL A. Otherwise always the absolute value of the input is stored.
(03-06-2015 04:27 PM)mbrethen Wrote: [ -> ]As Dieter pointed out, the program isn't fail safe but I like the fact that it does all the bookkeeping for you.
The following code is an optimized version of my previous code. It also realizes if the user tries to cancel input before a complete row has been entered. It even detects if there is no input at all.
Code:
W001 LBL W
W002 ABS
W003 IP
W004 STO B // b = base register#
W005 0,9 // set fractional part to 0,9 so that ISG increments and always tests true
W006 STO C
W007 STO D // start with entered base register
W008 +
W009 STO I // i = memory index, start with b
W010 ISG C // c = column index, start with 1
W011 ISG D // d = 1,mmm. Since m is not yet known, assume m is very large (e.g. 900)
W012 SF 1 // set flag 1 to indicate that no empty entry occured yet
W013 RCL D
W014 STO R // row index
W015 EQN [IP(R),IP(C)]
W016 STO A
W017 CLSTK
W018 ALL
W019 INPUT A // prompt A? [row,column]
W021 ABS // check whether x is scalar or vector
W021 LASTx
W022 [1,0]
W023 x
W024 ABS
W025 x≠y? // if x is a vector (i.e. no user input)
W026 GTO W038 // then determine #rows resp. #columns
W027 RCL I
W028 STO J
W029 ISG J
W030 STO(J) // otherwise store a non-zero value in variable (i+1)
W031 RCL A // recall input
W032 STO(I) // and store in variable (i)
W033 ISG I // increment register#
W034 ISG R // increment row index
W035 GTO W015 // get next row
W036 ISG C // increment column index
W037 GTO W013 // get next column
W038 FS? 1 // first occurence of R/S without entry?
W039 GTO W062 // then determine m = #rows
W040 SGN // at this point x = ip(r)
W041 LASTx
W042 x>y? // input cancelled before column was completed (row>1)?
W043 GTO W015 // then prompt again
W044 CLSTK // otherwise matrix is complete
W045 RCL C
W046 IP
W047 STO N
W048 SGN
W049 STO- N // determine n = #columns = c-1
W050 RCL M
W051 %
W052 RCL M
W053 RCLx N
W054 RCL+ B
W055 +
W056 x<>y // y still has the 1 left from the % command
W057 -
W058 1E3
W059 ÷
W060 RCL+ B // finished computing control number bbb.eeemm
W061 RTN // quit
W062 STO M // at this point x = ip(r)
W063 DSE M // determine m = #rows = r-1
W064 GTO W066 // m>0? then continue
W065 GTO W015 // else no entry at all was made, prompt again
W066 CF 1 // reset "first empty input" flag
W067 RCL M
W068 1E3
W069 ÷
W070 STO D
W071 ISG D // loop counter d = 1,mmm
W072 GTO W036 // get next column
This version even requires less memory than the previous ones. The 35s reports LN=243.
Dieter
(03-08-2015 01:28 PM)Dieter Wrote: [ -> ]More or less direkt translations of programs for other platforms are not always the best idea.
I'm finding that out
Quote:BTW: you should change your step W023 to RCL A. Otherwise always the absolute value of the input is stored.
Noted.
Quote:This version even requires less memory than the previous ones. The 35s reports LN=243.
Dieter
That's a 20% reduction from my translation; but the original HP-41 program was only 132 bytes! Does that suggest the HP-41 platform was more efficient?