home *** CD-ROM | disk | FTP | other *** search
/ Hot Shareware 32 / hot34.iso / ficheros / DGRAF / FRAIN196.ZIP / IF_ELSE.TXT < prev    next >
Text File  |  1997-05-06  |  13KB  |  292 lines

  1.  
  2.        FRACTINT'S NEW FLOW CONTROL INSTRUCTIONS FOR THE FORMULA PARSER
  3.  
  4.  
  5.     Version 19.6 of Fractint provides for flow control statements in user
  6.   created formulas.  This feature should make formulas more readable, and
  7.   preliminary testing indicates that more complicated formulas will run as
  8.   much as 2 to 3 times faster when the formula is written using the new
  9.   instructions.
  10.  
  11.     This tutorial provides an overview of the new feature.  It assumes that
  12.   the reader is familiar with the syntax of Fractint formulas.  If you are
  13.   new to Fractint, the documentation accompanying Fractint provides a good
  14.   start, and Bradley Beacham's tutorial (available in Library 3 of the
  15.   CompuServe Graphics Developers Forum as frmtut.zip, and at Noel Giffen's
  16.   Fractint web page - http://spanky.triumf.ca) will provide a more detailed
  17.   explanation of Fractint formula writing.  Sylvie Gallet's tutorial on PHC
  18.   and PTC formulas is a more advanced text, and is available at the same
  19.   sites. These tutorials are also included in the Fractint v. 19.6 package.
  20.  
  21.     Until Fractint v. 19.6, each section of a Fractint formula was always
  22.   executed one instruction at a time, sequentially through the section
  23.   without exception.  Formula writers worked out ingenious solutions to
  24.   achieve different results in a formula based on a testing of some
  25.   condition.  For example, if the writer wanted c to be equal to sin(z) if
  26.   x==y, and cos(z) if not, the formula would contain the following line:
  27.  
  28.     c = sin(z)*(x==y) + cos(z)*(x!=y)
  29.  
  30.     Each time this line is reached in the formula, which in the course of
  31.   drawing an image could be many millions of times, each element of the line
  32.   is computed, so both the x==y and the x!=y tests are evaluated (one of
  33.   which, of course, will be 0 and the other 1), and both sin(z) and cos(z)
  34.   are computed.  Obviously, it would be much more efficient to evaluate only
  35.   x==y, and then compute only sin(z) or cos(z) depending on the result.
  36.  
  37.  
  38. THE NEW FLOW CONTROL INSTRUCTIONS
  39.  
  40.     Four new formula instructions are now permitted in a Fractint formula.
  41.   They are:
  42.  
  43.       IF (expression)
  44.       ELSEIF (expression)
  45.       ELSE
  46.       ENDIF
  47.  
  48.     Each of these instructions must be a separate statement in the formula,
  49.   i.e. must end with a comma or an end-of-line character.
  50.     The easiest way to avoid problems with this requirement is to put each
  51.   of these instructions on a separate line.  The practice of the people
  52.   testing the new feature has been to capitalize the flow control
  53.   instructions and to indent the regular calculations which follow them.
  54.  
  55.     A group of these instructions beginning with IF and ending with ENDIF
  56.   constitutes a unit which I'll refer to as an "if block" of instuctions.
  57.   A formula may contain any number of if blocks, and if blocks may be nested
  58.   inside other if blocks.  The only limitation is that the end of the
  59.   initialization section (represented by a ":" in the formula) cannot be
  60.   inside an if block.
  61.  
  62.     An if block contains exactly one IF, exactly one ENDIF, no more than 1
  63.   ELSE (there may be none), and any number of ELSEIFs (there may be none),
  64.   but all ELSEIFs must precede the block's ELSE instruction.  The format is
  65.   therefore as follows:
  66.  
  67.       IF (expression)
  68.          statements
  69.       ELSEIF (expression)
  70.          statements
  71.       ELSEIF (expression)
  72.          statements
  73.       .
  74.       .
  75.       ELSE
  76.          statements
  77.       ENDIF
  78.  
  79.     ELSEIF (expression) is the equivalent of two flow control instructions,
  80.   an ELSE immediately followed by an IF ().  The difference between the
  81.   single and the separated instructions is that ELSEIF does not require its
  82.   own ENDIF, whereas ELSE followed by IF would require that the separate IF
  83.   have its own ENDIF.
  84.  
  85.     The example above, restated using these instructions, will read as
  86.   follows:
  87.  
  88.       IF (x==y)
  89.          c = sin(z)
  90.       ELSE
  91.          c = cos(z)
  92.       ENDIF
  93.  
  94.     Not only is this formulation intuitively easier to understand than the
  95.   earlier one, it also runs much faster, because only the elements necessary
  96.   to make the desired assignment to c are executed.
  97.  
  98.     The formula parser does the following with these instructions:
  99.  
  100.   1. Evaluate the expression inside the parentheses of the IF instruction.
  101.      Boolean expressions in Fractint (expressions which use the operators
  102.      ==, !=, >, <, >=, <=, && and ||) alway evaluate to (1,0) if the
  103.      expression is true and (0,0) if the expression is false.  The nature
  104.      of branching instructions is such that the expression in the
  105.      parentheses of an IF instruction will almost always be boolean, but
  106.      this is not a requirement.  Any expression which evaluates to a
  107.      single complex number is acceptable.  Thus, though unusual, the
  108.      instruction IF(x+y) is perfectly valid, since the result of x+y is a
  109.      complex number.
  110.  
  111.   2. Look at the real element, and only the real element, of the
  112.      expression.  If it is nonzero, the expression represents "true".
  113.      If the real element is zero, the expression represents "false".
  114.      Thus (1,0), (-1,0), and (3.14, 6) are all "true" results.  (0,0),
  115.      (0,1) and (0,-1) are all "false" results.
  116.  
  117.   3. If the expression is true, proceed to the next statement in the
  118.      formula without any skipping.
  119.  
  120.   4. If the expression is false, skip to the statement immediately following
  121.      the next flow control instruction in the if block (of necessity, an
  122.      ELSE, the ELSE element of an ELSEIF(), or ENDIF), and begin further
  123.      processing from there.
  124.  
  125.   5. If an ELSE or the ELSE portion of an ELSEIF() instruction is reached
  126.      in the course of processing, jump to the instruction following the
  127.      ENDIF at the end of that if block.
  128.  
  129.     Looking at the above example, the parser first evaluates the expression
  130.   x==y.  If it is true, the next statement, c = sin(x) is executed, and then,
  131.   the ELSE now being reached, execution jumps to the ENDIF.  If x==y is
  132.   false, execution jumps straight to the statement after the ELSE, which is
  133.   c = cos(x), and executes it, continuing on from there.
  134.  
  135.     With a little reflection you will realize that only one of the sets of
  136.   statements following flow control instructions in an if block is executed.
  137.   For example,
  138.  
  139.       IF (expr1)
  140.          group1_statements
  141.       ELSEIF (expr2)
  142.          group2_statements
  143.       ELSEIF (expr3)
  144.          group3_statements
  145.       ELSE
  146.          group4_statements
  147.       ENDIF
  148.  
  149.     If expr1 is true, the group1_statements will be executed and then the
  150.   execution will jump to the ENDIF.  The fact that expr2 or expr3 may be
  151.   true is irrelevant; the conditions will not be tested if expr1 is true.
  152.   If expr1 is false, then expr2 will be tested, and if true the
  153.   group2_statements will be executed, and when done the execution will jump
  154.   to the ENDIF.  expr3 is only evaluated if expr1 and expr2 are both false.
  155.   You can also see that the group4_statements will only be executed if all
  156.   three of the test expressions are false.
  157.  
  158.     If there is no ELSE statement in an if block, it is possible that none of
  159.   the calculation statements in the block will be executed.  For example,
  160.  
  161.       IF (expression)
  162.          statements
  163.       ENDIF
  164.  
  165.     will cause the statements to be executed only if the expression is true;
  166.   otherwise they are skipped entirely.
  167.  
  168. EXAMPLE
  169.  
  170.     Carr2821 is one of Bob Carr's many formulas which make use of the
  171.   formula branching technique developed by Sylvie Gallet.  It has received
  172.   much attention lately because of Lee Skinner's marvelous collection of 186
  173.   images derived from the formula.
  174.     Following is the original formula and an IF..ELSE rewrite of it.  In
  175.   addition to the straightforward switch from the old method of branching to
  176.   the new, you will see that the flow control instructions make much easier
  177.   the implementation of other short cuts which speed up execution.
  178.     The IF..ELSE rewrite produces the same images as the original, but in
  179.   about 1/2 the time, depending on your processor.
  180.  
  181.   Carr2821 {; Modified Sylvie Gallet frm. [101324,3444],1996
  182.             ; passes=1 needs to be used with this PHC formula.
  183.     b5=pixel-conj(0.1/pixel)
  184.     b4=pixel-flip(0.1/pixel)-conj(0.001/pixel),
  185.     c=whitesq*b4-(whitesq==0)*b4
  186.     z=whitesq*b5-(whitesq==0)*b5
  187.     c1=1.5*z^1.2,c2=2.25*conj(z),c3=3.375*flip(z),c4=5.0625*flip(z),
  188.     l1=real(p1),l2=imag(p1),l3=real(p2),l4=imag(p2),
  189.     bailout=16,iter=0:
  190.     t1=(iter==l1),t2=(iter==l2),t3=(iter==l3),t4=(iter==l4),
  191.     t=1-(t1||t2||t3||t4),z=z*t,c=c*t+c1*t1+c2*t2+c3*t3+c4*t4,
  192.     z=(|z|/5)+z*z+c-0.09/pixel
  193.     iter=iter+1
  194.     |z|<=bailout
  195.   }
  196.  
  197.   carr2821 {; Modified Sylvie Gallet frm. [101324,3444],1996
  198.             ; Converted to if.else by Sylvie Gallet and George Martin 3/97
  199.             ; passes=1 needs to be used with this PHC formula.
  200.      pixinv = 0.1/pixel
  201.      p9 = 0.9*pixinv
  202.      imagp1 = imag(p1)
  203.      imagp2 = imag(p2)
  204.      IF (whitesq)
  205.         z = zorig = pixel - conj(pixinv)
  206.         c = pixel - flip(pixinv) - conj(0.01*pixinv) - p9
  207.         mz = |z|
  208.      ELSE
  209.         z = zorig = conj(pixinv) - pixel
  210.         c = flip(pixinv) + conj(0.01*pixinv) - pixel - p9
  211.         mz = |z|
  212.      ENDIF
  213.      bailout = 16
  214.      iter = 0
  215.      :
  216.      IF (iter==p1)
  217.         z = mz = 0
  218.         c = 1.5*zorig^1.2 - p9
  219.      ELSEIF (iter==imagp1)
  220.         z = mz = 0
  221.         c = 2.25*conj(zorig) - p9
  222.      ELSEIF (iter==p2)
  223.         z = mz = 0
  224.         c = 3.375*flip(zorig) - p9
  225.      ELSEIF (iter==imagp2)
  226.         z = mz = 0
  227.         c = 5.0625*flip(zorig) - p9
  228.      ENDIF
  229.      z = mz*0.2 + z*z + c
  230.      mz = |z|
  231.      iter = iter + 1
  232.      mz <= bailout
  233.   }
  234.  
  235.  
  236. REWRITING OLD FORMULAS
  237.  
  238.     There are more than 1500 existing Fractint formulas which could be
  239.   written in IF..ELSE format.  If you have occasion to rewrite one, you
  240.   should test the rewrite to make sure it is drawing the identical images
  241.   that the original version did.  To perform this test, do the following:
  242.  
  243.   1. Using a .par file image entry which uses the formula, render the image
  244.      using the old formula, and save the image (e.g. as oldimage.gif).
  245.  
  246.   2. Using the same .par file image entry, render the image using the
  247.      rewritten formula, and save the image (e.g. as newimage.gif).
  248.  
  249.   3. Exit Fractint, and restart with the following command line options
  250.      selected:  debug=50  filename=oldimage.gif
  251.  
  252.   4. With oldimage.gif on the screen, hit <r> and select newimage.gif to
  253.      restore to the screen. Hit <CR>
  254.  
  255.   5. The effect of debug=50 is that the pixels which will be shown in the
  256.      second restored image will only be those which are different than the
  257.      image previously on the screen.  If the images are identical, you will
  258.      have a completely blank screen.
  259.  
  260.   6. Differences are saved to an ASCII file "cmperr".  Exit Fractint and
  261.      check this file to assure yourself that the two images were in fact
  262.      identical.
  263.  
  264.     Images drawn in floating point mode on a computer with a math coprocessor
  265.   or a 486 or higher processor may have slight pixel variation between an
  266.   original and an if..else rewrite because of certain optimizations
  267.   implemented in the "fast parser" code.  If you are seeing these variations
  268.   and want to make sure the rewritten formula is accurate, draw the images
  269.   using the original and rewritten formulas with the command line parameter
  270.   debug=322 selected.  This causes Fractint to skip the optimization code,
  271.   and differences caused by the optimizer will therefore be eliminated. If 
  272.   you still have differences and believe your rewrite is accurate, try again
  273.   with debug=90 selected. This eliminates the use of the fast parser 
  274.   entirely, and the original formula and your rewrite, if correct, should 
  275.   produce identical images. 
  276.  
  277.     
  278.     If you are satisfied that you have a good rewrite, post the revised
  279.   formula in a message in the Fractint forum on CompuServe, or send an email
  280.   with the revised formula to me (76440.1143@compuserve.com).  It will be
  281.   helpful if the message includes both the old and rewritten formula, and a
  282.   .par image entry using the formula so that we can easily verify the
  283.   accuracy of the rewrite.  Good rewrites will be added to the orgform
  284.   compilation of formulas in place of the old formula, with credit given to
  285.   the author of the rewrite.
  286.  
  287.     Thanks to Sylvie Gallet and Les StClair for their help in writing this
  288.   tutorial.
  289.  
  290.     George Martin
  291.     3/23/97
  292.