Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mandelbrot Set

367 views
Skip to first unread message

hughag...@gmail.com

unread,
Jul 1, 2016, 2:52:05 PM7/1/16
to
Over on comp.lang.lisp we had this thread:
https://groups.google.com/forum/#!topic/comp.lang.lisp/8XigMh1ujjM

Those guys want to use the Mandelbrot Set program as a bench-mark. This is a very bad idea because the Mandelbrot Set involves chaos --- it doesn't take long before that sequence of numbers becomes chaotic --- every program ends up with a different number of iterations because of tiny differences in the fuzziness of the least-significant digits that pretty soon end up fuzzing out the most-significant digits.

Anyway, I was asked to write a Mandelbrot Set program in Forth for comparison, so I did:



\ Mandelbrot Set --- ANS-Forth --- written by Hugh Aguilar
\ from Paul Rubin's C code in this thread:
\ https://groups.google.com/forum/#!topic/comp.lang.lisp/8XigMh1ujjM

\ ANS-Forth fails to support locals, so I had to use global variables.
\ ANS-Forth also fails to provide F>R FR@ FR> which could have also helped.

marker Mandelbrot.4th

: f+! ( adr -- ) \ float: n --
dup f@ f+ f! ;

: csqr ( -- ) \ float: a ai -- product producti
fover fdup f* fover fdup f* f- \ float: -- a ai a*a-ai*ai
frot frot \ float: -- a*a-ai*ai a ai
f* fdup f+ ; \ float: -- a*a-ai*ai a*ai+a*ai

: cabs ( -- ) \ float: a ai -- distance
fdup f* fswap
fdup f* f+
fsqrt ;

: s>f ( n -- ) \ float: -- n
s>d d>f ;

fvariable cc
fvariable cci
: <mandelbrot-iteration> ( -- count ) \ float: c cci -- z zi
fover cc f! fdup cci f! \ float: -- z zi \ Z starts as C not as origin
1 begin
csqr
fswap cc f@ f+ fswap cci f@ f+
1+
dup 1000 >= if exit then
fover fover cabs 100.0e f> if exit then
again ;

: mandelbrot-iteration ( -- count )
<mandelbrot-iteration>
fdrop fdrop ; \ discard z zi

fvariable dx
fvariable dy
fvariable x
fvariable y
fvariable x1
fvariable y1
variable nx
variable ny
variable sum
: mandelbrot-box ( nx ny -- sum ) \ float: x1 x2 y1 y2 --
ny ! nx ! 0 sum !
fover f- ny @ s>f f/ dy f! \ float: -- x1 x2 y1
y1 f! \ float: -- x1 x2
fover f- nx @ s>f f/ dx f! \ float: -- x1
x1 f! \ float: --
x1 f@ x f! 0 begin y1 f@ y f! 0 begin
x f@ y f@ mandelbrot-iteration sum +!
dup ny @ < while 1+ dy f@ y f+! repeat drop
dup nx @ < while 1+ dx f@ x f+! repeat drop
sum @ ;

: test ( -- )
256 256 0.0e 1.0e 0.0e 1.0e mandelbrot-box
\ 2 2 -2.0e 1.0e -1.0e 1.0e mandelbrot-box
cr ." sum = " u. ;

\ The TIME-TEST function is VFX only --- comment this out if you are using any other ANS-Forth compiler.
: time-test ( -- ) ticks test ticks swap - cr ." milliseconds: " . ;

hughag...@gmail.com

unread,
Jul 1, 2016, 3:35:24 PM7/1/16
to
On Friday, July 1, 2016 at 11:52:05 AM UTC-7, hughag...@gmail.com wrote:
> Over on comp.lang.lisp we had this thread:
> https://groups.google.com/forum/#!topic/comp.lang.lisp/8XigMh1ujjM
>
> Those guys want to use the Mandelbrot Set program as a bench-mark.

Here is a slightly more efficient version:


: f+! ( adr -- ) \ float: n --
dup f@ f+ f! ;

: csqr ( -- ) \ float: a ai -- product producti
fover fdup f* fover fdup f* f- \ float: -- a ai a*a-ai*ai
frot frot \ float: -- a*a-ai*ai a ai
f* fdup f+ ; \ float: -- a*a-ai*ai a*ai+a*ai

: cabs ( -- ) \ float: a ai -- distance
fdup f* fswap
fdup f* f+
fsqrt ;

: s>f ( n -- ) \ float: -- n
s>d d>f ;

fvariable cc
fvariable cci
: <mandelbrot-iteration> ( -- count ) \ float: c cci -- z zi
fover cc f! fdup cci f! \ float: -- z zi \ Z starts as C not as origin
1 begin
csqr
fswap cc f@ f+ fswap cci f@ f+
1+
dup 1000 >= if exit then
\ fover fover cabs 100.0e f> if exit then
fover fdup f* fover fdup f* f+ 10000.0e f> if exit then \ replaces last line

Pablo Hugo Reda

unread,
Jul 1, 2016, 3:40:50 PM7/1/16
to
Here is a fixed point version in :r4

---------------------------------------------------
#xmax #ymax #xmin #ymin

:calc | p q cx cy -- p q cx cy xn yn r
over dup *. over dup *. - pick4 + | xn
pick2 pick2 *. 2* pick4 + | xn yn
over dup *. over dup *. + | xn yn r
;

:mandel | x y -- x y v
over xmax xmin - sw */ xmin + | x y p
over ymax ymin - sh */ ymin + | x y p q
0 0 0 | cx cy it
( 255 <? )( >r | x y p q cx cy
calc | x y p q cx cy xn yn r
4.0 >? ( 4drop 3drop r> ; )
drop rot drop rot drop
r> 1+ )
nip nip nip nip
;

:scrman
0 ( sh <? )(
0 over setxy
0 ( sw <? )(
swap
mandel dup 8 << or dup 8 << or px!+
swap
1+ ) drop
1+ ) drop
;

:main
2.0 'xmax ! 2.0 'ymax !
-3.0 'xmin ! -2.0 'ymin !
scrman
blanco scr home " Mandelbrot" print
show
'exit >esc<
;

: main ;

hughag...@gmail.com

unread,
Jul 1, 2016, 3:57:15 PM7/1/16
to
On Friday, July 1, 2016 at 12:40:50 PM UTC-7, Pablo Hugo Reda wrote:
> Here is a fixed point version in :r4

What is :r4 ? Can I download this somewhere?

Pablo Hugo Reda

unread,
Jul 1, 2016, 4:22:38 PM7/1/16
to

WJ

unread,
Jul 2, 2016, 2:07:08 AM7/2/16
to
Paul Rubin's function seems to have off-by-one errors:

> const int mandelbrot_iteration(const double complex c)
> {
> int k = 1;
> double complex z = c;
> do {
> z = z*z + c;
> } while (k++ < 1000 && cabs(z) <= 100.0) ;
> return k;
> }

The minimal number that can be returned is 2;
the maximal is 1001. I believe those numbers
should be 1 and 1000.

Also, the correct way is to compare the magnitude of
the complex number to 2.0, not 100.0.

Also, z should not be initialized to c; it should start
at the origin.

The following code doesn't use a complex-number type;
just floats.

OCaml:

let max_iteration = 1000;;

(* Based on the wikipedia pseudocode *)
let count_iterations x0 y0 =
let rec loop iteration x y =
let xx = x *. x and yy = y *. y in
(* Exit when magnitude of complex number >= 2.0. *)
if (xx +. yy) < 4.0 && iteration < max_iteration then
loop (iteration+1) (xx -. yy +. x0) (2.0 *. x *. y +. y0)
else
iteration
in loop 0 0.0 0.0 ;;

let mandelbrot_box x1 x2 y1 y2 nx ny =
let dx = (x2 -. x1) /. float nx and
dy = (y2 -. y1) /. float ny and
sum = ref 0 in
for kx = 0 to nx do
let x = dx *. float kx +. x1 in
for ky = 0 to ny do
let y = dy *. float ky +. y1 in
sum := !sum + count_iterations x y
done
done ;
!sum ;;

Printf.printf "Minimal count_iterations: %d\n" (count_iterations 988.0 988.0);;
Printf.printf "Maximal count_iterations: %d\n" (count_iterations 0.0 0.0) ;;

for _ = 1 to 9 do
let t = Sys.time () in
print_int (mandelbrot_box 0.0 1.0 0.0 1.0 256 256) ;
Printf.printf " %.3f\n" ((Sys.time ()) -. t)
done



On an old WinXP laptop:

Minimal count_iterations: 1
Maximal count_iterations: 1000
13808106 0.313
13808106 0.312
13808106 0.328
13808106 0.313
13808106 0.312
13808106 0.313
13808106 0.312
13808106 0.313
13808106 0.312

jo...@planet.nl

unread,
Jul 2, 2016, 2:58:06 AM7/2/16
to
Julia442 at:
https://sites.google.com/site/win324th/sources
will use all the hardware threads of a CPU on your PC
to calculate and plot a mandelbrot.

Jos

m...@iae.nl

unread,
Jul 2, 2016, 3:12:38 AM7/2/16
to
On Saturday, July 2, 2016 at 8:07:08 AM UTC+2, WJ wrote:
[..]
> On an old WinXP laptop:
>
> Minimal count_iterations: 1
> Maximal count_iterations: 1000
> 13808106 0.313
> 13808106 0.312
> 13808106 0.328
> 13808106 0.313
> 13808106 0.312
> 13808106 0.313
> 13808106 0.312
> 13808106 0.313
> 13808106 0.312
[..]

Here is a 3 year old desktop.

0e DFVALUE Cre 0e DFVALUE Cim
0e DFVALUE Zr 0e DFVALUE Zi
0e DFVALUE ZrZr 0e DFVALUE ZiZi

CREATE out[] #1000000 ALLOT

: ShowMandel ( -- )
0 LOCAL Cnt
TIMER-RESET
#1000 0 DO
#1000 0 DO
I S>F 1e-3 F* 0.5e F- 4e F* TO Cre \ Range -2.0 to +2.0
I S>F 1e-3 F* 1.5e F* TO Cim \ Range 0.0 to +1.5
CLEAR Cnt CLEAR Zr CLEAR Zi
BEGIN
Zr FSQR FDUP TO ZrZr
Zi FSQR FDUP TO ZiZi
F+ 2e F<
WHILE
Zi Zr F*
ZrZr ZiZi F- Cre F+ TO Zr
FDUP F+ Cim F+ TO Zi
1 +TO Cnt Cnt #64 >
UNTIL THEN
Cnt out[] I J * + C!
LOOP
LOOP
CR ." Mandelbrot 1000 x 1000, " .ELAPSED ;

\ FORTH> ShowMandel many
\ Mandelbrot 1000 x 1000, 0.067 seconds elapsed.
\ Mandelbrot 1000 x 1000, 0.068 seconds elapsed.
\ Mandelbrot 1000 x 1000, 0.067 seconds elapsed.
\ ...

The 12-thread parallel one doesn't fit on the
bottom of this post.

-marcel

Paul Rubin

unread,
Jul 2, 2016, 3:58:20 AM7/2/16
to
"WJ" <w_a_...@yahoo.com> writes:
> Paul Rubin's function seems to have off-by-one errors:

I tried to do exactly what the Lisp code did, but I might not have
understood it (loop macro etc). I suppose I should trace both.

hughag...@gmail.com

unread,
Jul 3, 2016, 1:17:44 PM7/3/16
to
On Friday, July 1, 2016 at 12:35:24 PM UTC-7, hughag...@gmail.com wrote:
> : csqr ( -- ) \ float: a ai -- product producti
> fover fdup f* fover fdup f* f- \ float: -- a ai a*a-ai*ai
> frot frot \ float: -- a*a-ai*ai a ai
> f* fdup f+ ; \ float: -- a*a-ai*ai a*ai+a*ai
> ...
> fvariable cc
> fvariable cci
> : <mandelbrot-iteration> ( -- count ) \ float: c cci -- z zi
> fover cc f! fdup cci f! \ float: -- z zi \ Z starts as C not as origin
> 1 begin
> csqr
> fswap cc f@ f+ fswap cci f@ f+
> 1+
> dup 1000 >= if exit then
> \ fover fover cabs 100.0e f> if exit then
> fover fdup f* fover fdup f* f+ 10000.0e f> if exit then \ replaces last line
> again ;

I did a disassembly of these two words in VFX. The disassembly of FLIT seems to be incorrect. Why does it say 989.68? The number is supposed to be 10000.

see csqr
CSQR
( 004DFBB0 D9C1 ) FLD ST(1)
( 004DFBB2 D9C0 ) FLD ST
( 004DFBB4 DEC9 ) FMULP ST(1), ST
( 004DFBB6 D9C1 ) FLD ST(1)
( 004DFBB8 D9C0 ) FLD ST
( 004DFBBA DEC9 ) FMULP ST(1), ST
( 004DFBBC DEE9 ) FSUBP ST(1), ST
( 004DFBBE D9C9 ) FXCH ST(1)
( 004DFBC0 D9CA ) FXCH ST(2)
( 004DFBC2 D9C9 ) FXCH ST(1)
( 004DFBC4 D9CA ) FXCH ST(2)
( 004DFBC6 DEC9 ) FMULP ST(1), ST
( 004DFBC8 D9C0 ) FLD ST
( 004DFBCA DEC1 ) FADDP ST(1), ST
( 004DFBCC C3 ) NEXT,
( 29 bytes, 15 instructions )
ok
see <mandelbrot-iteration>
<MANDELBROT-ITERATION>
( 004DFCD0 D9C1 ) FLD ST(1)
( 004DFCD2 DB3D200C4600 ) FSTP TBYTE [00460C20]
( 004DFCD8 D9C0 ) FLD ST
( 004DFCDA DB3D300C4600 ) FSTP TBYTE [00460C30]
( 004DFCE0 8D6DFC ) LEA EBP, [EBP+-04]
( 004DFCE3 895D00 ) MOV [EBP], EBX
( 004DFCE6 BB01000000 ) MOV EBX, 00000001
( 004DFCEB 90 ) NOP
( 004DFCEC 90 ) NOP
( 004DFCED 90 ) NOP
( 004DFCEE 90 ) NOP
( 004DFCEF 90 ) NOP
( 004DFCF0 E8BBFEFFFF ) CALL 004DFBB0 CSQR
( 004DFCF5 D9C9 ) FXCH ST(1)
( 004DFCF7 DB2D200C4600 ) FLD TBYTE [00460C20]
( 004DFCFD DEC1 ) FADDP ST(1), ST
( 004DFCFF D9C9 ) FXCH ST(1)
( 004DFD01 DB2D300C4600 ) FLD TBYTE [00460C30]
( 004DFD07 DEC1 ) FADDP ST(1), ST
( 004DFD09 43 ) INC EBX
( 004DFD0A 81FBE8030000 ) CMP EBX, 000003E8
( 004DFD10 0F8C01000000 ) JL/NGE 004DFD17
( 004DFD16 C3 ) NEXT,
( 004DFD17 D9C1 ) FLD ST(1)
( 004DFD19 D9C0 ) FLD ST
( 004DFD1B DEC9 ) FMULP ST(1), ST
( 004DFD1D D9C1 ) FLD ST(1)
( 004DFD1F D9C0 ) FLD ST
( 004DFD21 DEC9 ) FMULP ST(1), ST
( 004DFD23 DEC1 ) FADDP ST(1), ST
( FPlit: 989.68 )
( 004DFD25 E8D6B5FEFF ) CALL 004CB300 FLIT
( 004DFD34 E877ACFEFF ) CALL 004CA9B0 FCMP2
( 004DFD39 85DB ) TEST EBX, EBX
( 004DFD3B 8B5D00 ) MOV EBX, [EBP]
( 004DFD3E 8D6D04 ) LEA EBP, [EBP+04]
( 004DFD41 0F8501000000 ) JNZ/NE 004DFD48
( 004DFD47 C3 ) NEXT,
( 004DFD48 EBA6 ) JMP 004DFCF0
( 004DFD4A C3 ) NEXT,
( 123 bytes, 39 instructions )
ok
see flit
FLIT
( 004CB300 5A ) POP EDX
( 004CB301 DB2A ) FLD TBYTE 0 [EDX]
( 004CB303 83C20A ) ADD EDX, 0A
( 004CB306 FFE2 ) JMP EDX
...
ok
see fcmp2
FCMP2
( 004CA9B0 83ED04 ) SUB EBP, 04
( 004CA9B3 895D00 ) MOV [EBP], EBX
( 004CA9B6 D9C9 ) FXCH ST(1)
( 004CA9B8 DED9 ) FCOMPP
( 004CA9BA 9B ) FWAIT
( 004CA9BB DFE0 ) FSTSW AX
( 004CA9BD 66250041 ) AND AX, 4100
( 004CA9C1 0FB7D8 ) MOVZX EBX, AX
( 004CA9C4 C3 ) NEXT,
( 21 bytes, 9 instructions )
ok

hughag...@gmail.com

unread,
Jul 4, 2016, 8:51:55 PM7/4/16
to
On Sunday, July 3, 2016 at 10:17:44 AM UTC-7, hughag...@gmail.com wrote:
> On Friday, July 1, 2016 at 12:35:24 PM UTC-7, hughag...@gmail.com wrote:
> > fover fdup f* fover fdup f* f+ 10000.0e f> if exit then >
> I did a disassembly of these two words in VFX. The disassembly of FLIT seems to be incorrect. Why does it say 989.68? The number is supposed to be 10000.
> ( FPlit: 989.68 )
> ( 004DFD25 E8D6B5FEFF ) CALL 004CB300 FLIT

Is this a bug in the VFX disassembler?

Cecil Bayona

unread,
Jul 5, 2016, 12:25:36 AM7/5/16
to
Might be a bug, in the "see" code on VFX 4.71 Standard compiler.

Ran a simple test, added two float numbers, the result was correct. but
it still shows the funny representation for 10000.0e

: testf 1.0e 10000.0e f+ f. ; ok
testf 10001. ok
see testf
TESTF
( 004D13A0 D9E8 ) FLD1
( FPlit: 989.68 )
( 004D13A2 E839D1FFFF ) CALL 004CE4E0 FLIT
( 004D13B1 DEC1 ) FADDP ST(1), ST
( 004D13B3 6A00 ) PUSH 00
( 004D13B5 8D6DFC ) LEA EBP, [EBP+-04]
( 004D13B8 895D00 ) MOV [EBP], EBX
( 004D13BB BBFFFFFFFF ) MOV EBX, FFFFFFFF
( 004D13C0 E8DBEDFFFF ) CALL 004D01A0 (F.)
( 004D13C5 5A ) POP EDX
( 004D13C6 2BD3 ) SUB EDX, EBX
( 004D13C8 8D6DFC ) LEA EBP, [EBP+-04]
( 004D13CB 895D00 ) MOV [EBP], EBX
( 004D13CE 8BDA ) MOV EBX, EDX
( 004D13D0 E8E7A8F3FF ) CALL 0040BCBC SPACES
( 004D13D5 FF1545704000 ) CALL [00407045] TYPE
( 004D13DB E898A8F3FF ) CALL 0040BC78 SPACE
( 004D13E0 C3 ) NEXT,
( 65 bytes, 17 instructions )

Second test with similar wacky results in the disassembly;

: testf 10001.0e 1.0e f- f. ; ok
ok
ok
testf 10000. ok
see testf
TESTF
( FPlit: 989.A68 )
( 004D13A0 E83BD1FFFF ) CALL 004CE4E0 FLIT
( 004D13AF D9E8 ) FLD1
( 004D13B1 DEE9 ) FSUBP ST(1), ST
( 004D13B3 6A00 ) PUSH 00
( 004D13B5 8D6DFC ) LEA EBP, [EBP+-04]
( 004D13B8 895D00 ) MOV [EBP], EBX
( 004D13BB BBFFFFFFFF ) MOV EBX, FFFFFFFF
( 004D13C0 E8DBEDFFFF ) CALL 004D01A0 (F.)
( 004D13C5 5A ) POP EDX
( 004D13C6 2BD3 ) SUB EDX, EBX
( 004D13C8 8D6DFC ) LEA EBP, [EBP+-04]
( 004D13CB 895D00 ) MOV [EBP], EBX
( 004D13CE 8BDA ) MOV EBX, EDX
( 004D13D0 E8E7A8F3FF ) CALL 0040BCBC SPACES
( 004D13D5 FF1545704000 ) CALL [00407045] TYPE
( 004D13DB E898A8F3FF ) CALL 0040BC78 SPACE
( 004D13E0 C3 ) NEXT,
( 65 bytes, 17 instructions )
ok

--
Cecil - k5nwa

hughag...@gmail.com

unread,
Jul 5, 2016, 1:48:13 AM7/5/16
to
On Monday, July 4, 2016 at 9:25:36 PM UTC-7, Cecil - k5nwa wrote:
> On 7/4/2016 7:51 PM, hughag...@gmail.com wrote:
> > On Sunday, July 3, 2016 at 10:17:44 AM UTC-7, hughag...@gmail.com wrote:
> >> On Friday, July 1, 2016 at 12:35:24 PM UTC-7, hughag...@gmail.com wrote:
> >>> fover fdup f* fover fdup f* f+ 10000.0e f> if exit then >
> >> I did a disassembly of these two words in VFX. The disassembly of FLIT seems to be incorrect. Why does it say 989.68? The number is supposed to be 10000.
> >> ( FPlit: 989.68 )
> >> ( 004DFD25 E8D6B5FEFF ) CALL 004CB300 FLIT
> >
> > Is this a bug in the VFX disassembler?
> >
> Might be a bug, in the "see" code on VFX 4.71 Standard compiler.
>
> Ran a simple test, added two float numbers, the result was correct. but
> it still shows the funny representation for 10000.0e

This is the second time that I've found a bug in VFX --- the first time Stephen Pelc only grudgingly fixed it and said that doing so was a waste of his time --- I remember that well because I was writing a VFX program for money at the time and the bug was a big stumbling block for me.

He brought out this version 4.71.3523 of VFX (Oct.8,2014) with the bug fixed --- also in the new version was a new license agreement that stated that MPE doesn't allow anybody to use the evaluation version of VFX for commercial software --- that was obviously aimed directly at me, because I was the only one doing that.

rickman

unread,
Jul 5, 2016, 2:02:38 AM7/5/16
to
That is a very common stipulation of evaluation software.

If you aren't paying someone for their work, do you really expect them
to let you use their work for your own profit?

Likely you were the first case they knew of who had intent to do this
and it made them realize this might be a problem they should deal with.

--

Rick C

lawren...@gmail.com

unread,
Jul 6, 2016, 3:46:14 AM7/6/16
to
On Tuesday, July 5, 2016 at 6:02:38 PM UTC+12, rickman wrote:

> If you aren't paying someone for their work, do you really expect them
> to let you use their work for your own profit?

That’s how all Free Software works.

Ron Aaron

unread,
Jul 6, 2016, 3:48:31 AM7/6/16
to
First of all, no: VFX isn't "Free Software". Secondly, see the GPL.

rickman

unread,
Jul 6, 2016, 11:33:29 AM7/6/16
to
That may be how some open source software works, but MPE eval software
is not "open source". It is licensed which is how Hugh knows the terms
changed, he read the license.

--

Rick C

lawren...@gmail.com

unread,
Jul 6, 2016, 10:56:16 PM7/6/16
to
On Wednesday, July 6, 2016 at 7:48:31 PM UTC+12, Ron Aaron wrote:
>
> On 06/07/2016 10:46, Lawrence D’Oliveiro wrote:
>>
>> On Tuesday, July 5, 2016 at 6:02:38 PM UTC+12, rickman wrote:
>>
>>> If you aren't paying someone for their work, do you really expect them
>>> to let you use their work for your own profit?
>>
>> That’s how all Free Software works.
>
> First of all, no: VFX isn't "Free Software".

Was the question specific to this piece of non-Free Software, then?

> Secondly, see the GPL.

Where in the GPL does it say I cannot profit from it?

lawren...@gmail.com

unread,
Jul 6, 2016, 10:57:19 PM7/6/16
to
On Thursday, July 7, 2016 at 3:33:29 AM UTC+12, rickman wrote:
> That may be how some open source software works ...

That is how ALL Open Source software works <https://opensource.org/osd-annotated>.

Cecil Bayona

unread,
Jul 6, 2016, 11:32:56 PM7/6/16
to
I do believe it's referred to as evaluation software, and therefore
subject to limits and not "open source". Stephen is free to set whatever
limits he chooses since it's his software, and once he realizes that
people are trying to use it for commercial endeavors then he might have
been moved to change the license to make it perfectly clear.

I used his software for a while before I bought a copy, and I recall
that limit being there, for evaluation and hobby use only, commercial
applications were not allowed.

--
Cecil - k5nwa

lawren...@gmail.com

unread,
Jul 7, 2016, 12:08:28 AM7/7/16
to
On Thursday, July 7, 2016 at 3:32:56 PM UTC+12, Cecil - k5nwa wrote:
> ... commercial applications were not allowed.

Trouble is, what does “commercial” mean? <https://www.techdirt.com/articles/20090602/2322205106.shtml>

It might not mean what you want it to mean <https://www.techdirt.com/articles/20140326/11405526695/german-court-says-creative-commons-non-commercial-licenses-must-be-purely-personal-use.shtml>.

HAA

unread,
Jul 7, 2016, 12:35:52 AM7/7/16
to
Cecil Bayona wrote:
> ...
> Second test with similar wacky results in the disassembly;
>
> : testf 10001.0e 1.0e f- f. ; ok
> ...
> see testf
> TESTF
> ( FPlit: 989.A68 )

Is this just a coincidence :)

$989A68 u. 10001000 ok



rickman

unread,
Jul 7, 2016, 12:45:03 AM7/7/16
to
That is how "Open Source" software works, not open source software.

--

Rick C

lawren...@gmail.com

unread,
Jul 7, 2016, 2:42:35 AM7/7/16
to
On Thursday, July 7, 2016 at 4:45:03 PM UTC+12, rickman wrote:
> On 7/6/2016 10:57 PM, Lawrence D’Oliveiro wrote:
>> On Thursday, July 7, 2016 at 3:33:29 AM UTC+12, rickman wrote:
>>> That may be how some open source software works ...
>>
>> That is how ALL Open Source software works
>> <https://opensource.org/osd-annotated>.
>
> That is how "Open Source" software works, not open source software.

You can call your proprietary stuff “freeware” or “Shared Source” (Microsoft likes that one), but don’t call it “open source”.

HAA

unread,
Jul 7, 2016, 2:59:14 AM7/7/16
to
Looks like it's printing in hex mode. To fix it make the following changes
to Ndp387.fth

[+switch dasm-switch
' flit run: base @ decimal \ *** add ***
DisAddr dup
cr ." ( FPlit: " f@ f. ." )"
FPCELL + set-DisAddr
base ! ; \ *** add ***
switch]





hughag...@gmail.com

unread,
Jul 7, 2016, 3:04:09 AM7/7/16
to
How do you figure that 989.68 is a hex number equal to 10000?

rickman

unread,
Jul 7, 2016, 3:14:04 AM7/7/16
to
No one is doing that. I believe you brought up open source software.
No, I see you said, "Free Software" (not sure just what that is since
you used capitals as if it's a proper noun). So I suppose we are off on
a tangent. Good you brought it back to proprietary software.

--

Rick C

hughag...@gmail.com

unread,
Jul 7, 2016, 3:22:02 AM7/7/16
to
What I was planning on doing, was distributing my cross-compiler as a binary-overlay for VFX --- people could use it in VFX-evaluation and not pay Stephen Pelc for this, and I wouldn't have to pay him either --- I wouldn't provide the source-code for my cross-compiler either.

If I was selling the cross-compiler, this would certainly violate his new rule (most likely, stopping me from doing this was the sole reason why he put the new rule in). Consider this scenario though --- I distribute the cross-compiler for free --- user's of my cross-compiler then hire me to write code for them in my cross-compiler, so my code being sold is not VFX code and is not ANS-Forth code either, and it runs on some target processor. Now have I broken the rule?

Anyway, Stephen Pelc can put any rule that he wants in his license agreement, and everybody who uses his VFX-evaluation must adhere to the rule, because the software belongs to Stephen Pelc. He could even put a rule in that says: "Nobody named Hugh Aguilar is allowed to use this software." I would have to adhere to the rule! This would be especially funny if there were some poor devil elsewhere in the world with the name Hugh Aguilar --- you can imagine his surprise when he reads the license agreement...

All this brouhaha arose because I got hired to write a cross-compiler and I did so in VFX-evaluation (I tried eForth first by was stymied by the lack of documentation). Within less than a week I discovered a bug in VFX. I complained about this bug but nothing happened, so I wrote some code to work around the bug, then I pressed forward. Then Stephen Pelc fixed the bug and released this new version containing the bug-fix and the anti-Hugh rule in the license agreement.

So, does it benefit Stephen Pelc to block me from using VFX-evaluation? When I write code in VFX-evaluation I find bugs and I tell Stephen Pelc about the bugs --- this benefits Stephen Pelc --- that bug that I found on my first week with VFX-evaluation had been in VFX since VFX was originally written, which was many years ago, and nobody else (including Stephen Pelc himself) had found it (most likely because nobody had ever written a cross-compiler in VFX before).

I don't really know what Stephen Pelc's reasons are for what he does --- he may not know either...

Cecil Bayona

unread,
Jul 7, 2016, 3:34:31 AM7/7/16
to
The ARM cross-compiler and other CPUs is written in and compiled by VFX
for Windows/Linux/OSX. I have not looked in the source to see if some
special non documented words are being used, I'm not sure I care as long
as it works, it's not possible to compile it with anything else anyway,
so vendor lock is in place and working well.

--
Cecil - k5nwa

HAA

unread,
Jul 7, 2016, 3:37:00 AM7/7/16
to
10000e pad f! pad f@ hex f. 989.68 ok




rickman

unread,
Jul 7, 2016, 3:39:12 AM7/7/16
to
Why don't you stop trying to rip off MPE and just buy the damn tool? If
you are getting paid to do the work, why would you *not* pay for the
tool? Or just use some other tool like a free copy of Win32Forth?

You can invent all sorts of paranoid reasons for MPE to restrict their
eval version, but it is clear to me that it is done to try to get people
to pay them for their work. Just as you are trying to get paid for your
work.

--

Rick C

hughag...@gmail.com

unread,
Jul 7, 2016, 3:40:33 AM7/7/16
to
I would be willing to bet a beer (and I love beer) that Stephen Pelc's cross-compiler is not written in ANS-Forth but is VFX-specific --- I have yet to see any of Stephen Pelc's code that was ANS-Forth --- he abandons ANS-Forth even when doing so is not necessary (his SYNONYM for example).

hughag...@gmail.com

unread,
Jul 7, 2016, 3:50:55 AM7/7/16
to
On Thursday, July 7, 2016 at 12:39:12 AM UTC-7, rickman wrote:
> Why don't you stop trying to rip off MPE and just buy the damn tool? If
> you are getting paid to do the work, why would you *not* pay for the
> tool?

I was only paid $400.

> Or just use some other tool like a free copy of Win32Forth?

Alex McDonald kicked me off of the Win32Forth mailing list because you accused me of being homosexual on the mailing list and I denied this in my usual strident way, then Alex McDonald said that I was off-topic.

Note that I'm not homosexual --- you were just being a troll, as usual.

> You can invent all sorts of paranoid reasons for MPE to restrict their
> eval version, but it is clear to me that it is done to try to get people
> to pay them for their work. Just as you are trying to get paid for your
> work.

Everybody wants to get paid...

Julian Fondren

unread,
Jul 7, 2016, 4:23:03 AM7/7/16
to
On Thursday, July 7, 2016 at 2:34:31 AM UTC-5, Cesyl - k5nwa wrote:
> The ARM cross-compiler and other CPUs is written in and compiled by VFX
> for Windows/Linux/OSX. I have not looked in the source to see if some
> special non documented words are being used, I'm not sure I care as long
> as it works, it's not possible to compile it with anything else anyway,
> so vendor lock is in place and working well.

Good heavens. We officially have Patient #1. Hugh's idiocy has been
demonstrated to be human-to-human transmittable. Is this the
beginning of the end? Are we all now at risk? If Communism ruined
the 20th century, will Straight Forth go on to ruin the 21st? Will
the masses demand that standards be destroyed -- except for this new
one -- on account of how standards somehow cause the non-standard to
be evil?

I still hold hope that mere physical therapy can fix this. Take an
infected person, discuss Forth with them over a period of a few days,
and slap them in the face every time they refer to a standard. The
theory is sound. The potential side effects, such as suppressing
normal healthy discussion of standards (or severe bruising) can be
borne.

We just need to try it. And it must be done now, while the disease is
so narrowly focused on Forth.

It's clear that argumentation and mockery have not sufficed. I don't
think any number of parentheses or scare quotes around "vendor
lock-in" can possibly reach a person dense enough to have complained
about that in the first place.

Hugh, See-sill, turn yourselves in today and get help. Your ancestors
fought, strove, survived, and died to bequeath this world as it is to
you. You can't possibly pay them back. You can only pay their gift
forward, by doing the same for future generations. Think of an
ungrateful, lazy, dirty, stupid child, who inherits a pristine
hundred-year-old mansion and then allows it to become so infested with
roaches that it can't possibly be cleaned -- it must be destroyed
completely, to its foundations, before another house can exist on that
spot. It is the position of such a child that you put yourself in
when you refuse to get slapped in the face a few dozen times, to cure
your Straight Forth before it can spread.


-- Julian

rickman

unread,
Jul 7, 2016, 10:27:54 AM7/7/16
to
On 7/7/2016 3:50 AM, hughag...@gmail.com wrote:
> On Thursday, July 7, 2016 at 12:39:12 AM UTC-7, rickman wrote:
>> Why don't you stop trying to rip off MPE and just buy the damn tool? If
>> you are getting paid to do the work, why would you *not* pay for the
>> tool?
>
> I was only paid $400.
>
>> Or just use some other tool like a free copy of Win32Forth?
>
> Alex McDonald kicked me off of the Win32Forth mailing list because you accused me of being homosexual on the mailing list and I denied this in my usual strident way, then Alex McDonald said that I was off-topic.
>
> Note that I'm not homosexual --- you were just being a troll, as usual.

Lol! I never said you were homosexual. I wouldn't want to insult the
homosexuals that way.


>> You can invent all sorts of paranoid reasons for MPE to restrict their
>> eval version, but it is clear to me that it is done to try to get people
>> to pay them for their work. Just as you are trying to get paid for your
>> work.
>
> Everybody wants to get paid...

Yes, the fact that you can't respect that says so much about you.

I see you are still carrying that horse.

--

Rick C

humptydumpty

unread,
Jul 20, 2016, 6:47:00 AM7/20/16
to
On Friday, July 1, 2016 at 9:52:05 PM UTC+3, hughag...@gmail.com wrote:
> Over on comp.lang.lisp we had this thread:
> https://groups.google.com/forum/#!topic/comp.lang.lisp/8XigMh1ujjM
>
> Those guys want to use the Mandelbrot Set program as a bench-mark. This is a very bad idea because the Mandelbrot Set involves chaos --- it doesn't take long before that sequence of numbers becomes chaotic --- every program ends up with a different number of iterations because of tiny differences in the fuzziness of the least-significant digits that pretty soon end up fuzzing out the most-significant digits.
>
> Anyway, I was asked to write a Mandelbrot Set program in Forth for comparison, so I did:
>
>
>
> \ Mandelbrot Set --- ANS-Forth --- written by Hugh Aguilar
> \ from Paul Rubin's C code in this thread:
> \ https://groups.google.com/forum/#!topic/comp.lang.lisp/8XigMh1ujjM
>
> \ ANS-Forth fails to support locals, so I had to use global variables.
> \ ANS-Forth also fails to provide F>R FR@ FR> which could have also helped.
>
> marker Mandelbrot.4th
>
> : f+! ( adr -- ) \ float: n --
> dup f@ f+ f! ;
>
> : csqr ( -- ) \ float: a ai -- product producti
> fover fdup f* fover fdup f* f- \ float: -- a ai a*a-ai*ai
> frot frot \ float: -- a*a-ai*ai a ai
> f* fdup f+ ; \ float: -- a*a-ai*ai a*ai+a*ai
>
> : cabs ( -- ) \ float: a ai -- distance
> fdup f* fswap
> fdup f* f+
> fsqrt ;
>
> : s>f ( n -- ) \ float: -- n
> s>d d>f ;
>
> fvariable cc
> fvariable cci
> : <mandelbrot-iteration> ( -- count ) \ float: c cci -- z zi
> fover cc f! fdup cci f! \ float: -- z zi \ Z starts as C not as origin
> 1 begin
> csqr
> fswap cc f@ f+ fswap cci f@ f+
> 1+
> dup 1000 >= if exit then
> fover fover cabs 100.0e f> if exit then
> again ;
>
> : mandelbrot-iteration ( -- count )
> <mandelbrot-iteration>
> fdrop fdrop ; \ discard z zi
>
> fvariable dx
> fvariable dy
> fvariable x
> fvariable y
> fvariable x1
> fvariable y1
> variable nx
> variable ny
> variable sum
> : mandelbrot-box ( nx ny -- sum ) \ float: x1 x2 y1 y2 --
> ny ! nx ! 0 sum !
> fover f- ny @ s>f f/ dy f! \ float: -- x1 x2 y1
> y1 f! \ float: -- x1 x2
> fover f- nx @ s>f f/ dx f! \ float: -- x1
> x1 f! \ float: --
> x1 f@ x f! 0 begin y1 f@ y f! 0 begin
> x f@ y f@ mandelbrot-iteration sum +!
> dup ny @ < while 1+ dy f@ y f+! repeat drop
> dup nx @ < while 1+ dx f@ x f+! repeat drop
> sum @ ;
>
> : test ( -- )
> 256 256 0.0e 1.0e 0.0e 1.0e mandelbrot-box
> \ 2 2 -2.0e 1.0e -1.0e 1.0e mandelbrot-box
> cr ." sum = " u. ;
>
> \ The TIME-TEST function is VFX only --- comment this out if you are using any other ANS-Forth compiler.
> : time-test ( -- ) ticks test ticks swap - cr ." milliseconds: " . ;

Hi!

Here is my try :)

FALIGN
HERE 5 FLOATS ALLOT
DUP CONSTANT DX
FLOAT+ DUP CONSTANT RE
FLOAT+ DUP CONSTANT DY
FLOAT+ DUP CONSTANT IM
FLOAT+ CONSTANT RADIUS
1e2 fdup f* RADIUS f!

: orbit ( -- u )
1000 Re f@ Im f@
BEGIN
dup
WHILE
fover fdup f* fover fdup f* f- Re f@ f+
frot frot
f* fdup f+ Im f@ f+
fover fdup f* fover fdup f* f+
Radius f@ f<
WHILE
1-
REPEAT THEN fdrop fdrop 1001 swap -
;
: init ( n m -- ; F: x1 x2 y1 y2 -- ; inits Re Im Dx Dy)
fover Im f!
fswap f- s>d d>f f/ Dy f!
fover Re f!
fswap f- s>d d>f f/ Dx f!
;
: mbox ( n m -- u; F: x1 x2 y1 y2 -- )
2dup init ( n m )
0 swap Re f@
0 DO ( n sum ; F: re )
over 0 DO
orbit +
Dx f@ Re f@ f+ Re f!
LOOP
fdup Re f!
Dy f@ Im f@ f+ Im f!
LOOP fdrop nip
;
: test ( -- )
256 256 0.0e 1.0e 0.0e 1.0e mbox cr ." sum = " u.
;


--
Have a nice day,
humptydumpty

hughag...@gmail.com

unread,
Jul 20, 2016, 10:22:23 AM7/20/16
to
On Wednesday, July 20, 2016 at 3:47:00 AM UTC-7, humptydumpty wrote:
> Here is my try :)
>
> FALIGN
> HERE 5 FLOATS ALLOT
> DUP CONSTANT DX
> FLOAT+ DUP CONSTANT RE
> FLOAT+ DUP CONSTANT DY
> FLOAT+ DUP CONSTANT IM
> FLOAT+ CONSTANT RADIUS
> 1e2 fdup f* RADIUS f!

I'm curious as to why you defined your globals like this. Why not just use FVARIABLE instead?

This isn't going to work on all ANS-Forth systems because some of them put the headers in the same place as the ALLOT data --- if CONSTANT changes HERE then your code won't work --- I tested your code on VFX and it was okay.

Note that in Straight Forth I require the headers to be somewhere other than where ALLOT and comma are, so this kind of code will work --- ANS-Forth is ambiguous though, and this kind of code may or may not work.
Well, I'll study your code in more depth later.

Everybody gets a different result:
13907805 HumptyDumpty --- VFX
13950170 me --- VFX
13959941 Paul Rubin --- GCC-fast
13959797 Paul Rubin --- GCC-regular
13950225 Nicolas Neuss --- SBCL

Paul Rubin says, in regard to the differing results: "That seems ok: the boundary of the Mandelbrot set is very chaotic and that's what makes it interesting."

This is what makes the Mandelbrot program uninteresting to me. How can anybody know if a program is correct or has bugs, if everybody gets a different result? Also, I don't understand any of this math --- its only purpose seems to be to make psychedelic posters for stoners' bedroom walls --- if it had some purpose that I could understand, then I would have some framework for thinking about how the math works.

I felt a lot more comfortable writing my LowDraw.4th program. Probability is pretty intuitive, and it has an obvious purpose, and it is easy to test for correctness (if all the probabilities add up to 1.0 you can feel pretty confident, although it is theoretically possible to have two bugs that exactly balance each other out).

Coos Haak

unread,
Jul 20, 2016, 11:02:41 AM7/20/16
to
Op Wed, 20 Jul 2016 07:22:21 -0700 (PDT) schreef hughag...@gmail.com:

> On Wednesday, July 20, 2016 at 3:47:00 AM UTC-7, humptydumpty wrote:
>> Here is my try :)
>>
>> FALIGN
>> HERE 5 FLOATS ALLOT
>> DUP CONSTANT DX
>> FLOAT+ DUP CONSTANT RE
>> FLOAT+ DUP CONSTANT DY
>> FLOAT+ DUP CONSTANT IM
>> FLOAT+ CONSTANT RADIUS
>> 1e2 fdup f* RADIUS f!
>
> I'm curious as to why you defined your globals like this. Why not just use FVARIABLE instead?
>
> This isn't going to work on all ANS-Forth systems because some of them put the headers in the same place as the ALLOT data --- if CONSTANT changes HERE then your code won't work --- I tested your code on VFX and it was okay.
>
The issue of headers inside or outside data space is moot here.
Look at the perfect usage of the line 'here 5 floats allot'

groet Coos

hughag...@gmail.com

unread,
Jul 20, 2016, 11:20:06 AM7/20/16
to
Oh, right --- I was wrong in thinking that CONSTANT was messing up the data area.

Still though, I must say that HumptyDumpty's code can be gratuitously complicated at times --- why not just use FVARIABLE that would be plain?

humptydumpty

unread,
Jul 20, 2016, 11:58:56 AM7/20/16
to
On Wednesday, July 20, 2016 at 6:20:06 PM UTC+3, hughag...@gmail.com wrote:
> On Wednesday, July 20, 2016 at 8:02:41 AM UTC-7, Coos Haak wrote:
> > Op Wed, 20 Jul 2016 07:22:21 -0700 (PDT) schreef hughaguilar:
> >
> > > On Wednesday, July 20, 2016 at 3:47:00 AM UTC-7, humptydumpty wrote:
> > >> Here is my try :)
> > >>
> > >> FALIGN
> > >> HERE 5 FLOATS ALLOT
> > >> DUP CONSTANT DX
> > >> FLOAT+ DUP CONSTANT RE
> > >> FLOAT+ DUP CONSTANT DY
> > >> FLOAT+ DUP CONSTANT IM
> > >> FLOAT+ CONSTANT RADIUS
> > >> 1e2 fdup f* RADIUS f!
> > >
> > > I'm curious as to why you defined your globals like this. Why not just use FVARIABLE instead?
> > >
> > > This isn't going to work on all ANS-Forth systems because some of them put the headers in the same place as the ALLOT data --- if CONSTANT changes HERE then your code won't work --- I tested your code on VFX and it was okay.
> > >
> > The issue of headers inside or outside data space is moot here.
> > Look at the perfect usage of the line 'here 5 floats allot'
> >
> > groet Coos
>
> Oh, right --- I was wrong in thinking that CONSTANT was messing up the data area.
>
> Still though, I must say that HumptyDumpty's code can be gratuitously complicated at times --- why not just use FVARIABLE that would be plain?

Hi!

On gforth-fast it is marginally faster than FVARIABLE version,
on VFX does not make any difference. :)

What is fascinanting (for me) on mandelbrot-set is that
at a scale of dimension things looks alike,
yet more distant are "alikes", more begins to look different
in such a way that do not get boring (almost not quick getting there :)
Yet at another scale, old "alikes" appears unexpectedly :)

humptydumpty

unread,
Jul 20, 2016, 12:02:59 PM7/20/16
to
Here FVARIABLE version:

include ../Lib/x86/Ndp387.fth

FVARIABLE Re
FVARIABLE Im
FVARIABLE Radius 1e2 fdup f* Radius f!

: orbit ( -- u )
1000 Re f@ Im f@
BEGIN
dup
WHILE
fover fdup f* fover fdup f* f- Re f@ f+
frot frot
f* fdup f+ Im f@ f+
fover fdup f* fover fdup f* f+
Radius f@ f<
WHILE
1-
REPEAT THEN fdrop fdrop 1001 swap -
;

FVARIABLE Dx
FVARIABLE Dy

: init ( n m -- ; F: x1 x2 y1 y2 -- ; inits Re Im Dx Dy)
fover Im f!
fswap f- s>d d>f f/ Dy f!
fover Re f!
fswap f- s>d d>f f/ Dx f!
;
: mbox ( n m -- u; F: x1 x2 y1 y2 -- )
2dup init ( n m )
0 swap Re f@
0 DO ( n sum ; F: re )
over 0 DO
orbit +
Dx f@ Re f@ f+ Re f!
LOOP
fdup Re f!
Dy f@ Im f@ f+ Im f!
LOOP
fdrop nip
;
: test ( -- )
256 256 0.0e 1.0e 0.0e 1.0e mbox
cr ." sum = " u.
;

\ The TIME-TEST function is VFX only --- comment this out if you are using any other ANS-Forth compiler.
: time-test ( -- ) ticks test ticks swap - cr ." milliseconds: " . ;

\ RESULT AMD FX 6100 4GHz OC
\ sum = 13907805
\ milliseconds: 100


--

hughag...@gmail.com

unread,
Jul 20, 2016, 12:35:52 PM7/20/16
to
On Wednesday, July 20, 2016 at 8:58:56 AM UTC-7, humptydumpty wrote:
> On Wednesday, July 20, 2016 at 6:20:06 PM UTC+3, hughag...@gmail.com wrote:
> > I must say that HumptyDumpty's code can be gratuitously complicated at times --- why not just use FVARIABLE that would be plain?

> Hi!
>
> On gforth-fast it is marginally faster than FVARIABLE version,
> on VFX does not make any difference. :)

Most likely, gForth uses CREATE DOES> in FVARIABLE --- in most Forth compilers, CREATE DOES> words are slow.

> What is fascinanting (for me) on mandelbrot-set is that
> at a scale of dimension things looks alike,
> yet more distant are "alikes", more begins to look different
> in such a way that do not get boring (almost not quick getting there :)
> Yet at another scale, old "alikes" appears unexpectedly :)

I was fascinated by chaos when I was younger --- I've become increasingly dull with age --- nowadays I just want to write programs that have a clear purpose (hopefully something useful) and are easy to verify for correctness.

> Have a nice day,

Thanks! You too!

Anton Ertl

unread,
Jul 21, 2016, 9:21:32 AM7/21/16
to
humptydumpty <oua...@gmail.com> writes:
[fvariable vs. some workaround]
>On gforth-fast it is marginally faster than FVARIABLE version,

They generate exactly the same code, so the performance difference you
saw probably came from some secondary effect (e.g., something like
cache conflicts), and is unlikely to be systematic.

fvariable x ok
falign here 1 floats allot constant y ok
: foo x y ; ok
simple-see foo
$7F723B0C6370 lit
$7F723B0C6378 <x>
$7F723B0C6380 lit
$7F723B0C6388 <140128593666832>
$7F723B0C6390 ;s ok

As you can see, both CONSTANT and FVARIABLE compile to a LIT, both in
0.7.0 and in the current development version.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2016: http://www.euroforth.org/ef16/

humptydumpty

unread,
Jul 21, 2016, 12:04:05 PM7/21/16
to
On Thursday, July 21, 2016 at 4:21:32 PM UTC+3, Anton Ertl wrote:
Hi!

It difference is (few percent maximum) and not systematic,
and maybe CPU dependent.
0 new messages