04-16-2024, 08:05 AM
Hi all,
A few months back, I ported Valentin's albillo efficient complex solver (see his article) from the 35S to the 42S and to the 32SII/DM32.
Porting it to the 42S was trivial, as both the 35S and the 42S can deal with complex numbers easily (on the stack and in storage registers).
Porting it to the 32SII/DM32 was another pair of shoes. Those only have a 2-level complex stack instead of 4, and lack complex registers. So porting the program was more complicated: not only every STO/RCL had to be doubled, but moreover, anything needing more than 2 numbers on the stack (like / followed by +) had to use temporary storage.
Porting it to the 41 was even more complicated, since the 41 doesn'have complex numbers at all. Well, you have the Advantage Pack's crude RPN routines, but those use registers, which is a headache when your program also needs a lot of registers ! You could use Angel Martin's awesome MCODE 41Z module, or even the TOULMATH module (which replicated the 15C complex stack in MCODE), but none of these ware available to the user back in the day, so this would be cheating...
I found a simple way, reading the software library on this very forum: Jean-Marc Baillard actually wrote his own 2-level stack RPN complex functions (here), with several improvements over the Math/Advantage Pack:
- No registers used at all;
- Simpler usage;
- Complete trigs and hyperbolics.
Jean-Marc also wrote his own complex solvers, which work fine. However, they are not as elegantly simple as Valentins's, they require 2 or 3 estimates, or even to compute first and second order derivatives, vs. only one estimate. But this gave me the idea of the port...
So, first key-in Jean-Marc's complex stack functions. Hint: rather than your fingers (only the text is provided), copy the text, paste into Free42/Plus42 (pasting is very powerful), and then export it into a 41C-compatible raw file than you can email to yourself !
As for the port itself, here we go. Please note that whenever Valentin used a lettered 35S complex register, I used the corresponding numbered register (e.g. X became 24) for the real part, and then I used registers as needed for the imaginary parts, starting with 01. Registers 07 to 18 are free to use in your own equations programs. Register 00 has to hold the equation program's name in alphanumerical form (use ASTO 00 to store it).
The program is called "RZVA" for "Root Z (complex) from Valentin Albillo"
Here is an example function to use. This is the first example from Valentin's article (Z^Z-R=0). The program expects the complex variable to be stored in X (from the 35S), which means register 26 (for the real part) and 01 (for the imaginary part). The constant R has to be stored in registers 9 (real) and 8 (imaginary). Here R = i, so R08 = 1 and R09 =0.
Juste do EQ1 ASTO 00 to store the equation, put 1 and 0 on the stack for the estimate (i), and voilà.
This works perfectlly... except for one thing: it is slow as hell !! Basically, take Valentin's timings in his article, they are expressed in seconds, well, take the same numbers expressed in minutes, you'll get an idea on how slow it is. I cheated by accelerating the emulated 41 in i41cx+. Even at max speed, this is still quite slow. The 41 is a slow machine to begin with, the RPN complex routines and constant need for intermediate storage doesn't help either... but if you are patient, now your bare-bones 41 can solve any complex equation !
Comments welcome of cours.
Cheers,
Vincent
A few months back, I ported Valentin's albillo efficient complex solver (see his article) from the 35S to the 42S and to the 32SII/DM32.
Porting it to the 42S was trivial, as both the 35S and the 42S can deal with complex numbers easily (on the stack and in storage registers).
Porting it to the 32SII/DM32 was another pair of shoes. Those only have a 2-level complex stack instead of 4, and lack complex registers. So porting the program was more complicated: not only every STO/RCL had to be doubled, but moreover, anything needing more than 2 numbers on the stack (like / followed by +) had to use temporary storage.
Porting it to the 41 was even more complicated, since the 41 doesn'have complex numbers at all. Well, you have the Advantage Pack's crude RPN routines, but those use registers, which is a headache when your program also needs a lot of registers ! You could use Angel Martin's awesome MCODE 41Z module, or even the TOULMATH module (which replicated the 15C complex stack in MCODE), but none of these ware available to the user back in the day, so this would be cheating...
I found a simple way, reading the software library on this very forum: Jean-Marc Baillard actually wrote his own 2-level stack RPN complex functions (here), with several improvements over the Math/Advantage Pack:
- No registers used at all;
- Simpler usage;
- Complete trigs and hyperbolics.
Jean-Marc also wrote his own complex solvers, which work fine. However, they are not as elegantly simple as Valentins's, they require 2 or 3 estimates, or even to compute first and second order derivatives, vs. only one estimate. But this gave me the idea of the port...
So, first key-in Jean-Marc's complex stack functions. Hint: rather than your fingers (only the text is provided), copy the text, paste into Free42/Plus42 (pasting is very powerful), and then export it into a 41C-compatible raw file than you can email to yourself !
As for the port itself, here we go. Please note that whenever Valentin used a lettered 35S complex register, I used the corresponding numbered register (e.g. X became 24) for the real part, and then I used registers as needed for the imaginary parts, starting with 01. Registers 07 to 18 are free to use in your own equations programs. Register 00 has to hold the equation program's name in alphanumerical form (use ASTO 00 to store it).
The program is called "RZVA" for "Root Z (complex) from Valentin Albillo"
Code:
01 LBL "RZVA"
02 LBL 01
03 STO 24
04 RDN
05 STO 01
06 1 E-4
07 STO 19
08 X^2
09 STO 20
10 0.5
11 STO 25
12 LBL 02
13 XEQ IND 00
14 0
15 RCL 25
16 XEQ "Z/"
17 STO 21
18 RDN
19 STO 02
20 RCL 19
21 ST+ 24
22 XEQ IND 00
23 STO 22
24 RDN
25 STO 03
26 RCL 19
27 ST- 24
28 ST- 24
29 XEQ IND 00
30 STO 23
31 RDN
32 STO 04
33 R^
34 RCL 03
35 RCL 22
36 XEQ "Z+"
37 RCL 02
38 RCL 21
39 XEQ "Z-"
40 0
41 RCL 20
42 XEQ "Z/"
43 STO 06
44 RDN
45 STO 05
46 RCL 03
47 RCL 22
48 RCL 04
49 RCL 23
50 XEQ "Z-"
51 0
52 RCL 19
53 ST+ 24
54 XEQ "Z/"
55 0
56 RCL 25
57 XEQ "Z*"
58 STO 23
59 RDN
60 STO 04
61 RCL 06
62 RCL 05
63 RCL 04
64 RCL 23
65 XEQ "Z/"
66 STO 22
67 RDN
68 STO 03
69 R^
70 RCL 02
71 RCL 21
72 XEQ "Z*"
73 RCL 04
74 RCL 23
75 XEQ "Z/"
76 1
77 -
78 CHS
79 X<>Y
80 CHS
81 X<>Y
82 RCL 25
83 XEQ "Z^X"
84 1
85 -
86 RCL 03
87 RCL 22
88 XEQ "Z/"
89 ST+ 24
90 RDN
91 ST+ 01
92 R^
93 RCL 01
94 RCL 24
95 XEQ "Z/"
96 R-P
97 RCL 20
98 X<Y?
99 GTO 02
100 RCL 01
101 RCL 24
102 R-P
103 RDN
104 STO 23
105 SIN
106 ABS
107 RCL 20
108 X<=Y?
109 GTO 03
110 RCL 23
111 COS
112 ENTER
113 ABS
114 X!=0?
115 /
116 RCL 01
117 RCL 24
118 R-P
119 X<>Y
120 RDN
121 *
122 STO 24
123 LBL 03
124 RCL 01
125 RCL 24
126 RTN
127 END
Here is an example function to use. This is the first example from Valentin's article (Z^Z-R=0). The program expects the complex variable to be stored in X (from the 35S), which means register 26 (for the real part) and 01 (for the imaginary part). The constant R has to be stored in registers 9 (real) and 8 (imaginary). Here R = i, so R08 = 1 and R09 =0.
Code:
01 LBL "EQ1"
02 RCL 01
03 RCL 24
04 RCL 01
05 RCL 24
06 XEQ "Z^Z"
07 RCL 08
08 RCL 09
09 XEQ "Z-"
10 RTN
11 END
Juste do EQ1 ASTO 00 to store the equation, put 1 and 0 on the stack for the estimate (i), and voilà.
This works perfectlly... except for one thing: it is slow as hell !! Basically, take Valentin's timings in his article, they are expressed in seconds, well, take the same numbers expressed in minutes, you'll get an idea on how slow it is. I cheated by accelerating the emulated 41 in i41cx+. Even at max speed, this is still quite slow. The 41 is a slow machine to begin with, the RPN complex routines and constant need for intermediate storage doesn't help either... but if you are patient, now your bare-bones 41 can solve any complex equation !
Comments welcome of cours.
Cheers,
Vincent