Post Reply 
How do I learn RPL and solve this problem with it?
09-25-2017, 08:04 PM
Post: #21
RE: How do I learn RPL and solve this problem with it?
I have not read the whole thread, but I'm wondering if the fact that the base resistor values form a, more or less, geometric series is used in some way.

Thus, the E12 series uses 12 values on each decade, this way the ratio between one value and the next is \(\sqrt[12]{10}=1.2115\ldots\). This way the E12 values are:
  • 1
  • \(\sqrt[12]{10}=1.2115\ldots\approx1.2\)
  • \((\sqrt[12]{10})^2=1.4677\ldots\approx1.5\)
  • \((\sqrt[12]{10})^3=1.7782\ldots\approx1.8\)
  • \((\sqrt[12]{10})^4=2.1544\ldots\approx2.2\)
  • \((\sqrt[12]{10})^5=2.6101\ldots\approx2.6\) (E24 value is 2.7)
  • \((\sqrt[12]{10})^6=3.1622\ldots\approx3.2\) (E24 value is 3.3)
  • \((\sqrt[12]{10})^7=3.8311\ldots\approx3.8\) (E24 value is 3.9)
  • \((\sqrt[12]{10})^8=4.6415\ldots\approx4.6\) (E24 value is 4.7)
  • \((\sqrt[12]{10})^9=5.6234\ldots\approx5.6\)
  • \((\sqrt[12]{10})^{10}=6.8129\ldots\approx6.8\)
  • \((\sqrt[12]{10})^{11}=8.2540\ldots\approx8.3\) (E24 value is 8.2)

I'm not yet worked this, but perhaps it would be possible to only search for resistor pairs that are zero steps apart, then one, then two,... and so on.

Regards.
Find all posts by this user
Quote this message in a reply
09-25-2017, 08:17 PM
Post: #22
RE: How do I learn RPL and solve this problem with it?
What a fantastic problem!!!

For UserRPL programming, download HPUserEdit 6 from hpcalc.org. Also download the file that converts the menus etc into English since the original is in... Spanish? HPUserEdit will let you write and debug your programs on the PC.

If your 50g came with the 184 page "User's Manual" then you should lock that book securely in a safe for now. It's more like a quick reference quide and will only serve to confuse you as a beginner. Use the "User's Guide" instead. It has much more detail.

The biggest problem with the User's Guide has to do with the 4 major modes of operation of the 50g: RPN vs. Algebraic input, and Soft Menus vs. choose boxes. Because of these modes, the User's Guide is full of things that say:

Now to do XYZ in RPN mode, enter these keys (half-page examples follows). If you're using algebraic mode, do this (another half page example follows). The above assume that you're using choose boxes. If you have soft menus, your screens will look like this... and this...

For this reason, you might want to consider using the 48GX User's Guide instead. It's all RPN and all soft menus.
Find all posts by this user
Quote this message in a reply
09-25-2017, 08:27 PM
Post: #23
RE: How do I learn RPL and solve this problem with it?
(09-25-2017 06:36 PM)mfleming Wrote:  Hi guys,

I believe you've been misled by the OP's approach of pre-computing all possible values of two resistors in parallel (combinatorial explosion), when in reality there are only a few combinations of two resistors that will meet the original criteria of being within 1% of the desired resistance value.

I agree, there's 4 or 5 valid values, no need to precompute anything.
The basic tasks can be broken into:
  1. Find the smallest resistor in E12 that is >= requested.
  2. Find the largest resistor in E12 <= 2*requested.
  3. Make a list of all valid resistors in E12 between them (only 4 or 5 total, since 1.211^4 > 2)
  4. Compute the second resistor needed for each case, but in each case finding the closest E12 resistor to the computed value.
  5. Compute the error for each case, make sure is within tolerance.
  6. Present the choice to the user in a nice way

Note that 1, 2 and 4 are basically the same, lookup the E12 resistor given a value, but in one case get the lower bound, in the other the upper and the third is closest match. Perhaps a single routine can handle all 3 cases. Task #3 can also reuse the same routine, since the next valid resistor would be the closest match to R*1.211 (with R being a valid E12 resistor).
That's the simplest way I see it. And that's not taking anybody by the hand, as each task is a project on itself.
So the first goal would be a routine that given any value, finds the lower, upper and closest match in the E12 series.
Find all posts by this user
Quote this message in a reply
09-26-2017, 01:02 AM
Post: #24
RE: How do I learn RPL and solve this problem with it?
I'm no good at the mathematics behind all this, I've been a bit lost. However, I realised that there's also a real-world value of each resistor, not just a theoretic L<R<U where L and U are the lower/upper 5% bounds. As soon as you add a resistor which ALSO has that same 5% tolerance, you have to hope that for an exact match, your chosen resistors aren't both at the lower edges of their tolerance bands (or higher edges) affecting how close their real (not nominal) value will be to the required theoretic value. Will the two resistors that are low still fall within 5% of the combined value? Ditto for two high resistors in parallel or series.

(Post 99)

Regards, BrickViking
HP-50g |Casio fx-9750G+ |Casio fx-9750GII (SH4a)
Visit this user's website Find all posts by this user
Quote this message in a reply
09-26-2017, 06:03 AM
Post: #25
RE: How do I learn RPL and solve this problem with it?
(09-25-2017 08:27 PM)Claudio L. Wrote:  - cut -

About the resistors in series, I realized since a while (without proof) that likely one goes picking the largest one that fits the value and then the second largest that first the remaining value.

I guess this approach won't be that valid with 3+ resistors, because the algorithm described above is greedy.

For the parallel resistors, I did not analyse the formula (I just took it as it is), but now I realize that is pretty the same - and very close to egyptian fractions indeed.
I take the value that fits closer to 1/R and then the value that is closer to the remaining value.

Once again, this should work because the values to pick are two. Would they be more, then it would be more challenging.

Thus the list of resistor precomputed surely speeds up the problem, but it is not needed to have all the combination precomputed (although it is a nice challenge of packing that data on the 50g).

Anyway both ways are interesting, the naive "don't let me think about the formula" brings certain challenges due to the scale of the problem, the more pondered "ok let's see what could be a shorter way" bring the challenge to verify that certain observations/decisions works (best case: a proof, worst case: check against all the possible combinations)

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
09-26-2017, 12:06 PM
Post: #26
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 01:02 AM)brickviking Wrote:  I'm no good at the mathematics behind all this, I've been a bit lost. However, I realised that there's also a real-world value of each resistor, not just a theoretic L<R<U where L and U are the lower/upper 5% bounds. As soon as you add a resistor which ALSO has that same 5% tolerance, you have to hope that for an exact match, your chosen resistors aren't both at the lower edges of their tolerance bands (or higher edges) affecting how close their real (not nominal) value will be to the required theoretic value. Will the two resistors that are low still fall within 5% of the combined value? Ditto for two high resistors in parallel or series.

(Post 99)

This is an important point. Also, standard 5% resistors have greater thermal variation than 1% resistors, so I don't think it's realistic to try to get a match within 1% of the desired value. IMHO a better definition of the problem is to sort the viable combinations by closeness to the desired value and pick the best one.

John
Find all posts by this user
Quote this message in a reply
09-26-2017, 01:02 PM
Post: #27
RE: How do I learn RPL and solve this problem with it?
I'd solve it like so:
  1. Sort the list of resistor values.
  2. Copy the list into an array for faster access (see below).
  3. For the resistor whose value is closest to the desired resistance. This is your starting point for a solution.
  4. For each resistor in the set
  5. Subtract it from the target resistance. Find the resistor in the set with this value, or the two that are closest.
  6. Compute the resistance of putting these in series. If the resistance is better than your best solution so far, then replace the solution with the new one.
  7. Now do the same for connecting in parallel: compute the value that gets you to the target, find the values closest to it and if the answer is better than before, then use it.


To help with this, you should write (or find) a binary search function for finding a value in an array. I'd call it binSearchLEQ. It finds the closest value that is less than or equal to a given value. It returns the INDEX to the value, not the value itself. That way you can get the next largest item easily. The binary search is why you want to work with an array: finding the N'th value in an array takes constant time, whereas finding the Nth value in a list takes N time.

That should be fast enough. A faster way would start at each end of the array and work towards the center. At each step you'd pick a value from one side and then move find the value on the other side that gives the best fit. This way the whole process would make one pass for finding the best serial combination. For parallel combinations it might be more involved.
Find all posts by this user
Quote this message in a reply
09-26-2017, 02:29 PM
Post: #28
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 01:02 AM)brickviking Wrote:  I'm no good at the mathematics behind all this, I've been a bit lost. However, I realised that there's also a real-world value of each resistor, not just a theoretic L<R<U where L and U are the lower/upper 5% bounds. As soon as you add a resistor which ALSO has that same 5% tolerance, you have to hope that for an exact match, your chosen resistors aren't both at the lower edges of their tolerance bands (or higher edges) affecting how close their real (not nominal) value will be to the required theoretic value. Will the two resistors that are low still fall within 5% of the combined value? Ditto for two high resistors in parallel or series.

(Post 99)

You have a point there. The error in each resistor doesn't really matter much, and here's why:
He wants to replace R (with a certain error, let's say 1%) with 2 parallel resistors that also come with a certain error of 1%.

1/R=1/R1+1/R2, therefore let's say both R1 and R2 are at the lower bound of error (the real R1'=0.99*R1, and R2'=0.99*R2) it turns out that:

1/R' = 1/R1'+1/R2' = 1/0.99*(1/R1+1/R2) = 1/(0.99*R)

The same will happen if you pick the upper bounds, (just with 1.01 instead of 0.99). In other words, 2 resistors in parallel with a certain tolerance will cause the resulting resistance to be within the same tolerance.
However, if the selected pair has an error you'll have that bias + the original tolerance. For example if the selected R1 and R2 produce a value that is 1% higher, you'll have a maximum error of 2% and a minimum of 0%, biased in the same direction.
So the user needs to pick the pair that produces the smallest error and accept that little bias, otherwise you'll be forced to use resistors with a smaller tolerance than the original requirement, so the result stays within bounds.
But that should be up to the designer, the problem at hand should find all 4 or 5 combinations and present them to the designer. The designer in the end will pick the closest pair, or whatever pair he can find in stock.
Find all posts by this user
Quote this message in a reply
09-26-2017, 02:50 PM
Post: #29
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 06:03 AM)pier4r Wrote:  Thus the list of resistor precomputed surely speeds up the problem, but it is not needed to have all the combination precomputed (although it is a nice challenge of packing that data on the 50g).

I wouldn't be so sure it speeds up the problem. You'll be searching through a large list of pairs, which is not necessarily any faster than computing 4 or 5 values on the fly. It's just a couple of additions and divisions versus a long loop of comparisons (only subtractions in the end, but we could be talking in the hundreds until you find all the valid combinations through the list).
Find all posts by this user
Quote this message in a reply
09-26-2017, 02:55 PM
Post: #30
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 02:50 PM)Claudio L. Wrote:  I wouldn't be so sure it speeds up the problem. You'll be searching through a large list of pairs, which is not necessarily any faster than computing 4 or 5 values on the fly. It's just a couple of additions and divisions versus a long loop of comparisons (only subtractions in the end, but we could be talking in the hundreds until you find all the valid combinations through the list).

I meant: the list of resistors (that are 96) is good to have in a precomputed form.

While the list of all the possible solutions (that should be 9000 items) is not needed.

My bad for my poor English, sorry.

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
09-26-2017, 04:37 PM
Post: #31
RE: How do I learn RPL and solve this problem with it?
(09-25-2017 08:04 PM)emece67 Wrote:  I have not read the whole thread, but I'm wondering if the fact that the base resistor values form a, more or less, geometric series is used in some way.

Thus, the E12 series uses 12 values on each decade, this way the ratio between one value and the next is \(\sqrt[12]{10}=1.2115\ldots\). This way the E12 values are:
  • 1
  • \(\sqrt[12]{10}=1.2115\ldots\approx1.2\)
  • \((\sqrt[12]{10})^2=1.4677\ldots\approx1.5\)
  • \((\sqrt[12]{10})^3=1.7782\ldots\approx1.8\)
  • \((\sqrt[12]{10})^4=2.1544\ldots\approx2.2\)
  • \((\sqrt[12]{10})^5=2.6101\ldots\approx2.6\) (E24 value is 2.7)
  • \((\sqrt[12]{10})^6=3.1622\ldots\approx3.2\) (E24 value is 3.3)
  • \((\sqrt[12]{10})^7=3.8311\ldots\approx3.8\) (E24 value is 3.9)
  • \((\sqrt[12]{10})^8=4.6415\ldots\approx4.6\) (E24 value is 4.7)
  • \((\sqrt[12]{10})^9=5.6234\ldots\approx5.6\)
  • \((\sqrt[12]{10})^{10}=6.8129\ldots\approx6.8\)
  • \((\sqrt[12]{10})^{11}=8.2540\ldots\approx8.3\) (E24 value is 8.2)

I'm not yet worked this, but perhaps it would be possible to only search for resistor pairs that are zero steps apart, then one, then two,... and so on.

Great insight! I know AWG wire diameters follow a geometric progression, but I wasn’t aware of this happening in resistor series.

This RPL program will generate all 192 values of the E192 series, if I have verified them correctly:

« PUSH -3. SF -105. SF 10. 192. XROOT 191. NDUPN { 1. } 1 ROT
FOR i DUP i GET ROT * +
NEXT 100. * 0. RND 186. 920. PUT POP
»

EVAL

{ 100. 101. 102. 104. 105. 106. 107. 109. 110. 111. 113. 114. 115. 117. 118. 120. 121. 123. 124. 126. 127. 129. 130. 132. 133. 135. 137. 138. 140. 142. 143. 145. 147. 149. 150. 152. 154. 156. 158. 160. 162. 164. 165. 167. 169. 172. 174. 176. 178. 180. 182. 184. 187. 189. 191. 193. 196. 198. 200. 203. 205. 208. 210. 213. 215. 218. 221. 223. 226. 229. 232. 234. 237. 240. 243. 246. 249. 252. 255. 258. 261. 264. 267. 271. 274. 277. 280. 284. 287. 291. 294. 298. 301. 305. 309. 312. 316. 320. 324. 328. 332. 336. 340. 344. 348. 352. 357. 361. 365. 370. 374. 379. 383. 388. 392. 397. 402. 407. 412. 417. 422. 427. 432. 437. 442. 448. 453. 459. 464. 470. 475. 481. 487. 493. 499. 505. 511. 517. 523. 530. 536. 542. 549. 556. 562. 569. 576. 583. 590. 597. 604. 612. 619. 626. 634. 642. 649. 657. 665. 673. 681. 690. 698. 706. 715. 723. 732. 741. 750. 759. 768. 777. 787. 796. 806. 816. 825. 835. 845. 856. 866. 876. 887. 898. 909. 920. 931. 942. 953. 965. 976. 988. }

For E96, take the first element of the list and every second element, counting from the second;
For E48, take the first element of the list and every fourth element, counting from the second... and so on. For series with two significant digits, the values should be rounded accordingly. I haven’t checked these, though.

Regards,

Gerson.
Find all posts by this user
Quote this message in a reply
09-26-2017, 06:20 PM (This post was last modified: 09-26-2017 06:21 PM by Dieter.)
Post: #32
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 01:02 PM)David Hayden Wrote:  I'd solve it like so:
(...)

Great, finally a possible method that is better than "brute force". ;-)

I tried a similar, but somewhat different approach. Here is how it works:

Let T be the target resistance.
Now do the following for all resistors > T and ≤ 2T:
  1. Pick the first/next value for R1 from the E12 series
  2. Calculate the value of R2, which is the resistor parallel to R1 that yields a total resistance of T
  3. Take the two closest resistors R2a and R2b and determine the total resistance R1||R2a and R1||R2b
    Or simply consider only the resistor R2c that is closest to R2.
  4. If the tolerance is not yet met, repeat with next R1
  5. Else display R1 and R2a or R2b and quit

Instead of quitting as soon as a combination within the allowed tolerance is found you can also run through all possible R1 (i.e. all resistors > T and ≤ 2T) and return the combination with the overall lowest deviation. But due to the individual tolerances of the two resistors this may not make much sense. On the other hand this returns the best possible combination even if it is not within tolerance.

Here is an example:

Try to find a combination for a target resistance of T = 350 Ω

The first larger R1 in the E12 series is 390 Ω
R2 = 350*390 / (390–350) = 3412,5 Ω
So R2a = 3300 Ω and R2b = 3900 Ω
390*3300 / (390+3300) = 348,78 Ω which is T – 0,35%
390*3900 / (390+3900) = 354,55 Ω which is T + 1,30%
The first value (3300 Ω) is within tolerance, so we already got a solution.
Otherwise repeat these steps with R1 = 470, 560 and 680 Ω.
Higher R1 values are not required, as 820 Ω already is > 2*350 Ω.

This way a combination of two parallel resistors can be found. Here the best result was 348,78 Ω. In a final step, the gap to 350 Ω can be closed with another 1,2 Ω resistor in series. But since we are already within the tolerance of the individual resistors this is not really required.

What do you think?

Dieter
Find all posts by this user
Quote this message in a reply
09-26-2017, 06:37 PM (This post was last modified: 09-26-2017 06:41 PM by Claudio L..)
Post: #33
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 02:55 PM)pier4r Wrote:  I meant: the list of resistors (that are 96) is good to have in a precomputed form.

Here's an idea for you: just have a list of the 12 basic ones, counting from 1.0, 1.2,1.5...

You can always split a number with MANT and XPON. Since MANT gives you the mantissa 1.0 < x < 10.0 it works perfect. All we need to add is a 10 at the end of the list, and we are guaranteed the mantissa falls within the list.
Then at the end we can multiply back by the XPON and there you go, or you can multiply the list by the XPON first, and work with the whole number, your choice.

EDIT: Just to clarify, not to multiply directly by the XPON, but by the ALOG of the XPON.
Find all posts by this user
Quote this message in a reply
09-26-2017, 06:46 PM
Post: #34
RE: How do I learn RPL and solve this problem with it?
Here's a program for the HP Prime using some ideas from Claudio to speed it up (for me PPL is much easier than RPL for writing quick programs such as this one) :

Code:
Suffix(n)
BEGIN
 CASE
  IF 3≤LOG(n)<6 THEN n:=STRING(n/1ᴇ3)+"K" END;
  IF 6≤LOG(n)<9 THEN n:=STRING(n/1ᴇ6)+"M" END;
  DEFAULT n
 END;
END;


EXPORT RES(R)
BEGIN
LOCAL val:={10,12,15,18,22,27,33,39,47,56,68,82};
LOCAL rng:={.1,1,1ᴇ1,1ᴇ2,1ᴇ3,1ᴇ4,1ᴇ5,1ᴇ6};
LOCAL res:={};
LOCAL a,b,j,k,r0,r1,r2,rp;

FOR j FROM 1 TO 8 DO
 res:=CONCAT(res,val*rng(j));
END;

FOR j FROM 1 TO SIZE(res) DO
  a:=res(j);
  IF a>2*R THEN BREAK; END;
  IF a≥R THEN
    FOR k FROM j TO SIZE(res) DO
      b:=res(k);
      rp:=a*b/(a+b);
      IF ABS(R-rp)<ABS(R-r0) THEN
        r0:=rp;r1:=a;r2:=b;
      END; 
    END;
  END;
END;

r0:=ROUND(r0,−5);
rp:=ROUND(%CHANGE(R,r0),2);

PRINT(Suffix(r1)+" || "+Suffix(r2)+" = "+Suffix(r0)+" ("+rp+")");
RETURN {r1,r2,r0,rp};
END;

RES(523000) returns: 560K || 8.2M = 524.2K (0.23)
RES(117) returns: 120 || 4.7K = 117.01 (0.01)
RES(28) returns: 56 || 56 = 28 (0)

Note: the special character that may not be rendered correctly is the small E for EEX
Find all posts by this user
Quote this message in a reply
09-26-2017, 06:57 PM
Post: #35
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 06:37 PM)Claudio L. Wrote:  Here's an idea for you: just have a list of the 12 basic ones, counting from 1.0, 1.2,1.5...

You can always split a number with MANT and XPON. Since MANT gives you the mantissa 1.0 < x < 10.0 it works perfect. All we need to add is a 10 at the end of the list, and we are guaranteed the mantissa falls within the list.
Then at the end we can multiply back by the XPON and there you go, or you can multiply the list by the XPON first, and work with the whole number, your choice.

EDIT: Just to clarify, not to multiply directly by the XPON, but by the ALOG of the XPON.

First: thanks for sharing.

Second: for practical purposes (optimization comes after correct resolution) is it important? I mean if the list would be 200 or 2000 elements, I would find your tip needed due to memory constraints, but 96 elements are not that much even for userRPL I'd say (if they are precomputed). Or do I miss something?

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
09-26-2017, 07:01 PM (This post was last modified: 09-26-2017 08:37 PM by Dieter.)
Post: #36
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 04:37 PM)Gerson W. Barbosa Wrote:  Great insight! I know AWG wire diameters follow a geometric progression, but I wasn’t aware of this happening in resistor series.

Unfortunately the actual resistor values are sometimes rounded up, sometimes down. But there is a way to calculate the nominal values of the E12 series. Here is a code snippet in VBA:

Code:
Function R(i)

a = i Mod 12 + 1
If a < 8 Then w = 0.83 * 1.22 ^ a Else w = 0.88 * 1.204 ^ a
w = Round(w, 1)
R = 10 ^ (i \ 12) * w

End Function
Note: "\" stands for integer division.

Enter an integer i and R(i) returns the i-th value of the E12 series, starting at 1 Ω.

0 => 1
1 => 1,2
2 => 1,5
3 => 1,8
...
10 => 6,8
11 => 8,2
12 => 10
13 => 12
14 => 15
...
53 => 27000
54 => 33000
...

Dieter
Edited to correct an error in the program code
Find all posts by this user
Quote this message in a reply
09-26-2017, 08:22 PM
Post: #37
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 06:57 PM)pier4r Wrote:  First: thanks for sharing.

Second: for practical purposes (optimization comes after correct resolution) is it important? I mean if the list would be 200 or 2000 elements, I would find your tip needed due to memory constraints, but 96 elements are not that much even for userRPL I'd say (if they are precomputed). Or do I miss something?

Nope, not missing anything. Just that I didn't see that as an optimization, my head sees it more as: argument reduction / algorithm / output. And my suggestion was in the argument reduction category, so I suggested it first, that's all.
Find all posts by this user
Quote this message in a reply
09-26-2017, 08:25 PM
Post: #38
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 07:01 PM)Dieter Wrote:  Unfortunately the actual resistor values are sometimes rounded up, sometimes down. But there is a way to calculate the nominal values of the E12 series. Here is a code snippet in VBA:

Code:
Function R(i)

a = i Mod 12 + 1
If a < 8 Then w = 0.83 * 1.22 ^ a Else w = 0.88 * 1.204 ^ a
b = Round(b, 1)
R = 10 ^ (i \ 12) * w

End Function

b=Round(b,1) doesn't seem right, as b is undefined?
Find all posts by this user
Quote this message in a reply
09-26-2017, 08:36 PM (This post was last modified: 09-26-2017 08:40 PM by Dieter.)
Post: #39
RE: How do I learn RPL and solve this problem with it?
(09-26-2017 08:25 PM)Claudio L. Wrote:  b=Round(b,1) doesn't seem right, as b is undefined?

Oops, sorry, this "b" is supposed to be a "w".
I will correct the original post.

Dieter
Find all posts by this user
Quote this message in a reply
09-26-2017, 10:20 PM (This post was last modified: 09-26-2017 10:21 PM by pier4r.)
Post: #40
RE: How do I learn RPL and solve this problem with it?
So still a greedy algorithm but a bit better than "compute all" Quite quick on the 50g.

Code:

\<<
    @3167 
    "resistorToApprox" DROP
    
    
    { 10 12 15 18 22 27 33 39 47 56 68 82 }  "baseResistors" DROP
    { 1. 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 
5.6 6.8 8.2 10. 12. 15. 18. 22. 
27. 33. 39. 47. 56. 68. 82. 100. 
120. 150. 180. 220. 270. 330. 390. 
470. 560. 680. 820. 1000. 1200. 1500. 
1800. 2200. 2700. 3300. 3900. 4700. 
5600. 6800. 8200. 10000. 12000. 15000. 
18000. 22000. 27000. 33000. 39000. 47000.
 56000. 68000. 82000. 100000. 120000. 150000.
 180000. 220000. 270000. 330000. 390000. 
470000. 560000. 680000. 820000. 1000000. 1200000. 
1500000. 1800000. 2200000. 2700000. 3300000. 3900000. 
4700000. 5600000. 6800000. 8200000. 10000000. 12000000. 
15000000. 18000000. 22000000. 27000000. 33000000. 39000000. 
47000000. 56000000. 68000000. 82000000. } "allResistors" DROP
    DUP SIZE "allResistorsNumber" DROP
    { 0.1 10 100 1000 10000 100000 1000000 } "resistorRanges" DROP
    {} "resultSerial" DROP
    {} "resultParallel" DROP
    0 "value1" DROP
    0 "value2" DROP
    {} "allResistorsListTemp" DROP
    {} "allResistorsListTemp2" DROP
    0 "inputValueTmp" DROP
    
    \->
    @input
    resistorToApprox
    
    @localVar
    baseResistors
    allResistors
    allResistorsNumber
    resistorRanges
    resultSerial
    resultParallel
    value1
    value2
    allResistorsListTemp
    allResistorsListTemp2
    inputValueTmp
    
    \<<
      \<<
        @first we build the list of all possible resistors from the base one.
    
        @for every element in the range of resistors we expand the list of available
        @resistors
        1 resistorRanges SIZE
        FOR position
          'allResistors'
          baseResistors
          resistorRanges position GET
          *
          STO+
        NEXT
        
        @now we order the resistors, although it is not strictly needed for the result
        allResistors :2:LSORT EVAL 'allResistors' STO      
        @we can also save the result as precomputed list
      \>> 
      DROP
        @not needed, we have the list precomputed now.
    
      @here we have all the resistors needed.
      
      @####
      @serial
      
      IF
        resistorToApprox 2 >
          @only in this case serial can be done
          @otherwise the value is too little.
      THEN
        1 2
        START
          allResistors
          resistorToApprox value1 - allResistorsNumber LNDUP
          \<=
            @after this operation we have on the stack a list
            @that reports all positions less than the input value.
          1 MPOS 1 LROT HEAD
            @we have the position of the largest element in the list
            @smaller than the value
            @(would be nice if the list of davidM
            @would include even those little commands so one has not to think about them)
          allResistors SWAP GET 'value1' STO 
          
          'resultSerial' value1 STO+
        NEXT
        
        @output
        resultSerial @resistors
        resultSerial LSUM @value
        DUP resistorToApprox SWAP %T @percentage
        100 SWAP - @percentage difference
        2 RND
      END
      
      @####
      @parallel
      
      "parallel"
      
      0 'value1' STO
      1 2
      START
        allResistors INV
        resistorToApprox INV value1 - allResistorsNumber LNDUP
        \<=
          @after this operation we have on the stack a list
          @that reports all positions less than the input value.
          @now since we have the invese the larger elements are smaller
          @so what we need is the first element smaller
        1 POS
          @we have the position of the largest element in the list
          @smaller than the value
        allResistors SWAP GET 'value1' STO 
        
        'resultParallel' value1 STO+
        value1 INV 'value1' STO
      NEXT
      
      @output
      resultParallel @resistors
      resultParallel INV LSUM INV 2 RND @value
      DUP resistorToApprox SWAP %T @percentage
      100 SWAP - @percentage difference
      2 RND
    \>>
  \>>


note that serial will return positive percentage difference, parallel negative ones (because the inverted value is always bigger than the given one).

Since it is greedy, I found at least some counterexample to the question "does it found always the best solution?" for example with 28, the serial solution is ok the parallel one is off.

Anyway I learned that better to proceed by increasing improvements rather than being stuck.

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)