Mombu the Programming Forum sponsored links

Go Back   Mombu the Programming Forum > Programming > Do***enting postscript code
User Name
Password
REGISTER NOW! Mark Forums Read

sponsored links


Reply
 
1 9th March 00:03
roger willcocks
External User
 
Posts: 1
Default Do***enting postscript code



In no particular order:

Your code suffers from 'add one to x' commenting. Anybody reading your code
can be expected to understand Postscript syntax, so all they should need are
a few pointers as to what the code is intended to do, plus additional
details for anything particularly subtle.

There is no need, for instance, for you to tell us what 'for' does; but if
you do, it would be handy if you got it right. 'for''s arguments are
"initial increment limit proc" but you pass "lowerlimit upperlimit no_points
proc" which will only work in the case where upperlimit is equal to one
(which coincidentally is your test case.)

My biggest problem in understanding your code is that nowhere does it tell
me what trapintegrate does. My second problem is that you can't see the code
for the comments.

As you will have noticed, the problem with using 'index' is that the
reference point changes every time. In this instance, building a local
dictionary to contain your parameters is favourite. However where possible
you should still avoid using local variables.

One other point, pre-computing 'h' will lose accuracy; you should multiply
by width and divide by count eact time. (Consider the situation where count
is very large.) I would define a local procedure for this:


%!
% integrate by t****zium rule
% rkww 9 Aug 03
%
% |\ /|\ /|\ /|
% | | | | | | |
% +-+-+-+-+-+-+
%
% area under curve is sum of areas under each t****zium. Area under
% each t****zium is ( f(lhs) + f(rhs) / 2 ) * width-of-each-t****zium

% Note that f(rhs) of one t****zium is f(lhs) of next, hence total
% area is width-of-each-t****zium *
% ( sum( f(inner points) ) + f(leftmost) / 2 + f(rightmost) / 2 )
%
% Syntax:
% {function} lowerlimit upperlimit no_points _trapintegrate_ result

/trapintegrate {
10 dict begin

/no_points exch def
/upperlimit exch def
/lowerlimit exch def
/proc exch def

/trap_width_mul {
upperlimit lowerlimit sub mul no_points div
} def

0 % ac***ulator
1 1 no_points 1 sub {
trap_width_mul lowerlimit add proc add
} for

lowerlimit proc 2 div add
upperlimit proc 2 div add

trap_width_mul
end
} def

/mysqr { dup mul } def
{ mysqr } 0 1 40 trapintegrate

==

--
Roger
  Reply With Quote


  sponsored links


2 9th March 00:03
allan adler
External User
 
Posts: 1
Default Do***enting postscript code



Thanks to Roger Will****s for his helpful comments. I'm confused by one
point, namely:


whereas in reply to my earlier posting about contamination of local variables,

I didn't really understand the latter (i.e. the earlier) comment but took
it as a caution that using local dictionaries didn't necessarily mean my
problem of contamination is "local variables" is thereby solved. That, and
Lee Sau Dan's exhortation to write more "native" postscript code by avoiding
the use of expensive def's, induced me to eliminate internal def's entirely.
That did make it a little harder to write the code at first, but at every
stage I was able to make sense of it by writing down what the operand stack
had to look like.

So, I guess I'm confused as to whether there is something to worry about in
using local dictionaries or not and, if so, what is it exactly? Could one
give an example showing ********ly what might be wrong with it? If it is
really completely safe, it would be much more convenient to use local
dictionaries.

Ignorantly,
Allan Adler
ara@zurich.ai.mit.edu

************************************************** **************************
* *
* Disclaimer: I am a guest and *not* a member of the MIT Artificial *
* Intelligence Lab. My actions and comments do not reflect *
* in any way on MIT. Moreover, I am nowhere near the Boston *
* metropolitan area. *
* *
************************************************** **************************
  Reply With Quote
3 9th March 00:03
roger willcocks
External User
 
Posts: 1
Default Do***enting postscript code


As with any programming task, you want to balance clarity and conciseness.
PostScript is an extremely flexible language and there are often may ways of
expressing the same intention. My exhortation to avoid local variables is a
stylistic issue; PostScript is a stack-based language and the stack provides
a convenient place to store (anonymous) intermediate values.

My comment about 'index' was also intended as a stylistic one: your earlier
sample code seemed to me to overuse this facility.

I would suggest that, to minimise the likelihood of problems, any
definitions you make should go in a private dictionary, and you should make
good use of the stack to minimise the definitions you need to make. But the
balance between naming things and using the stack is at the end of the day a
stylistic one.

Regarding worries with local dictionaries, the point is that definitions
within a dictionary higher on the dictionary stack hide those lower down.
Names are resolved to procedures or variables as they are encountered at
runtime (remember, PostScript is an interpreted language), which can have 'interesting' effects:[*]
PS> /add2 { 2 add } def
PS> /add { sub } def
PS> 1 add2 ==
-1

In this example, a new definition of 'add' was stored in the topmost
dictionary on the dictionary stack, hiding the existing definition in
systemdict. This is BY DESIGN. This is the way Postscript works. There are
no local variables in Postscript (to quote Lee Sau Dan), only dictionaries
and stacks.

[Note: it is in fact possible to ensure add2 always uses the proper 'add',
but the details are not relevant here.] Consider too:
PS> /weeble 123 def
PS> 10 dict begin
PS> weeble == 123
PS> /weeble (frog) def
PS> weeble == (frog)
PS> end
PS> weeble ==
123

In this example, the 'frog' definition (in a temporary dictionary) overrode
a preexisting definition in an earlier dictionary on the stack. 'end'
discarded the temporary dictionary and the old definition reappeared.

'save' and 'restore' can play a part too. Consider:
PS> /add2 { 2 add } def
PS> save
PS> /add { sub } def
PS> 1 add2 == -1
PS> restore
PS> 1 add2 ==
3

Here 'restore' undid all the changes to VM made since the corresponding
'save'. This included removing the new definition of 'add'. This is the
nearest PostScript gets to 'scoping' of variables.

Incidentally, dictionaries don't /have/ to be on the dictionary stack, you
can create them and name them just like any other object.
PS> /mydict 10 dict def
PS> mydict /foo (yoghurt) put

You only need to put them on the dictionary stack of you want them to play a
part in name resolution at runtime:
PS> foo ==
%%[ Error: undefined; OffendingCommand: foo ]%%
PS> mydict begin
PS> foo == (yoghurt)
PS> end

Hope this helps,
[*] If you don't have access to a real Postscript printer with serial line
attached, one way to try out these examples is to download (free) RoPS 5.3
(level one PostScript, Windows platform) from http://www.rops.org. The
'executive.ps' sample program gives you access to an interactive PostScript
console.

--
Roger
http://www.rops.org
  Reply With Quote
4 9th March 00:04
quite
External User
 
Posts: 1
Default Do***enting postscript code


One way to avoid the problem is to use structured variable names. For
instance, include the procedure name in each variable.

/trapintegrate
{
/trapintegrate::no_points exch def
etc.

The :: has no special meaning to PostScript, but it may help to make
you confortable with the concepts.

This will not help in the case of recursion, of course.
----------------------------------------
Aandi Inston quite@dial.pipex.com http://www.quite.com
Please support usenet! Post replies and follow-ups, don't e-mail them.
  Reply With Quote


  sponsored links


5 18th March 07:04
External User
 
Posts: 1
Default Do***enting postscript code


Allan> That, and Lee Sau Dan's exhortation to write more "native"
Allan> postscript code by avoiding the use of expensive def's,
Allan> induced me to eliminate internal def's entirely.

I'm glad that it worked!


Allan> That did make it a little harder to write the code at
Allan> first, but at every stage I was able to make sense of it by
Allan> writing down what the operand stack had to look like.

Yeah. Have a look at some Postscript code that comes with


Fortunately, the authors put comments explaining the stack contents at
important points, so that the code isn't that impossible to follow.
(And those comments saves me from the need of pulling out a notepad
and a pencil to work out what the stack looks like as the routine is run.)
Allan> So, I guess I'm confused as to whether there is something
Allan> to worry about in using local dictionaries or not and, if
Allan> so, what is it exactly?

1) Dictionaries are more expensive.

2) In Postscript Level 1, you have to know precisely the size of your
dictionary, or else you get a dictionary overflow (is that the
name?). You could avoid that by always OVER-estimating your need.
But that translates to: wasting memory. The situation is better in
Postscript Level 2 (and later), because dictionaries can grow in
size on the fly. e.g. you can simply write "0 dict begin ... def
... def ... end". But bear in mind that growing a dictionary
normally takes time linear to the number of existing entries there,
plus overhead of reallocating memory.

3) The dictionary stack itself may overflow. I think mose PS
interpreters are designed with the assumption that a MUCH larger
operand stack is needed than the dictionary stack.


So, it's generally more expensive, in terms of space and time, to use
local dictionaries. The only thing you get form this is: programming
time, esp. if you're not yet fluent in Postscript.
Allan> Could one give an example showing ********ly what might be
Allan> wrong with it? If it is really completely safe, it would be
Allan> much more convenient to use local dictionaries.

I don't think so. It depends on whether you speak Postscript fluently
or not. I'd find
/incr { 1 add } def
much more convenient and readable than your
/incr { 1 dict begin /x exch def /x x 1 add def x end } def

Having said so, I still use local dictionaries in some cases:

1) For write-once-and-dump code. I often hand-edit Postscript files
generated by other programs and do something like adjusting the
margins, scaling the page, etc. There is no much sense in wasting
MY time to optimize such code, which will be dumped once I've got
the printout, unless the Postscript Printer is really that
handicapped to handle it.

2) For writing the draft versions of some complicated procedures, esp.
when the calling interface has not been finalized yet. Using the
local-variables approach let's me change the order of operands and
add/remove operands in the interface more easily. However, I'd
usually start to convert it to the stack-oriented style once the
interface is fixed.


For _generic_ Postscript procedures, which are meant to be used in a
wide range of Postscript files, I always stick to the stack-oriented
approach.


--
Lee Sau Dan §õ¦u´°(Big5) ~{@nJX6X~}(HZ)

E-mail: danlee@informatik.uni-freiburg.de
Home page: http://www.informatik.uni-freiburg.de/~danlee
  Reply With Quote
6 18th March 07:04
External User
 
Posts: 1
Default Do***enting postscript code


Aandi> One way to avoid the problem is to use structured variable
Aandi> names. For instance, include the procedure name in each
Aandi> variable.

Aandi> /trapintegrate { /trapintegrate::no_points exch def etc.

Aandi> The :: has no special meaning to PostScript, but it may
Aandi> help to make you confortable with the concepts.

Aandi> This will not help in the case of recursion, of course.

Another disadvantage is the higher load exerted on the symbol table
(dictionaries) of the Postscript interpreter.


--
Lee Sau Dan §õ¦u´°(Big5) ~{@nJX6X~}(HZ)

E-mail: danlee@informatik.uni-freiburg.de
Home page: http://www.informatik.uni-freiburg.de/~danlee
  Reply With Quote
7 18th March 07:04
quite
External User
 
Posts: 1
Default Do***enting postscript code


Higher compared to what? Only to working completely without
variables. As I've often found, this is very expensive in programmer
time...
----------------------------------------
Aandi Inston quite@dial.pipex.com http://www.quite.com
Please support usenet! Post replies and follow-ups, don't e-mail them.
  Reply With Quote
8 18th March 07:04
lee sau dan
External User
 
Posts: 1
Default Do***enting postscript code


Aandi> Higher compared to what?

Compared to a more native PS code, which uses a stack oriented approach.
Aandi> Only to working completely without variables. As I've often
Aandi> found, this is very expensive in programmer time...

Yeah. That's a tradeoff. But if you start to "think in Postscript",
that won't cost too much time. Somtimes, having to invent variable
names for some immediate results gets me stuck (when writing in other
languages). Resorting to naming them "i", "j", "k", ... or "v1",
"v2", "v3", ... isn't better than thinking in terms of stack contents.


--
Lee Sau Dan §õ¦u´°(Big5) ~{@nJX6X~}(HZ)

E-mail: danlee@informatik.uni-freiburg.de
Home page: http://www.informatik.uni-freiburg.de/~danlee
  Reply With Quote
9 18th March 07:05
allan adler
External User
 
Posts: 1
Default Do***enting postscript code


Can you please recommend some specific files to look at? I'm having trouble
finding what you're referring to in the ghostscript-8.00 distribution.

Allan Adler
ara@zurich.ai.mit.edu

************************************************** **************************
* *
* Disclaimer: I am a guest and *not* a member of the MIT Artificial *
* Intelligence Lab. My actions and comments do not reflect *
* in any way on MIT. Moreover, I am nowhere near the Boston *
* metropolitan area. *
* *
************************************************** **************************
  Reply With Quote
10 27th March 09:28
allan adler
External User
 
Posts: 1
Default Do***enting postscript code


I finally found it in ghostscript-8.00/lib and it is do***ented as Lee Sau Dan
described. Part of my problem in finding it was that I didn't assume that the
code was to be found in .ps files and for some reason imagined that there
were .c files that contained internal examples of code generation for
postscript.

Ignorantly,
Allan Adler
ara@zurich.ai.mit.edu

************************************************** **************************
* *
* Disclaimer: I am a guest and *not* a member of the MIT Artificial *
* Intelligence Lab. My actions and comments do not reflect *
* in any way on MIT. Moreover, I am nowhere near the Boston *
* metropolitan area. *
* *
************************************************** **************************
  Reply With Quote
Reply


Thread Tools
Display Modes




Copyright © 2006 SmartyDevil.com - Dies Mies Jeschet Boenedoesef Douvema Enitemaus -
666