|
From: Daniel J S. <dan...@ie...> - 2006-05-29 22:20:17
|
This seems like a bug, even though the syntax is incorrect... but a user might think the syntax is correct if gnuplot doesn't complain but rather returns a non-zero value that will always test positive.
gnuplot> print defined("foo")
141158968
gnuplot> print defined("foo")
141159440
gnuplot> print defined("foo")
141159544
gnuplot> print defined("foo")
141159880
gnuplot> print defined("foo")
141160112
gnuplot> print defined("foo")
141160216
Also, would it be useful to extend defined() from just variables to functions as well? Say, return 1 if user defined variable, 2 if internal variable, 3 if user defined function, 4 if internal function.
That way, the defined() function could be used inside stat.inc as
if (defined(gamma)!=3) gamma(x) = exp(lgamma_nat(x))
then get rid of these comments like:
# If you have the lgamma() function compiled into gnuplot, you can use
# alternate definitions for some PDFs. For larger arguments this will result
# in more efficient evalution. Just uncomment the definitions containing the
# string `lgamma', while at the same time commenting out the originals.
# NOTE: In these cases the recursive definition for lgamma() is NOT sufficient!
As soon as someone starts uncommenting/commenting code it becomes confusing.
Last, how about an internally defined 'eps' or something similar to represent float machine precision?
Oh, one other thing. Any interest in a complex version of the gamma function?
Dan
|
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-05-30 00:22:56
|
On Monday 29 May 2006 03:28 pm, Daniel J Sebald wrote:
> This seems like a bug, even though the syntax is incorrect... but a user might think the syntax is correct if gnuplot doesn't complain but rather returns a non-zero value that will always test positive.
>
> gnuplot> print defined("foo")
> 141158968
We don't have a user-visible TBOOLEAN type,
so any non-zero value represents "TRUE"
> Also, would it be useful to extend defined() from just variables to functions as well?
> Say, return 1 if user defined variable, 2 if internal variable, 3 if user defined function,
> 4 if internal function.
What would you do with this information?
> That way, the defined() function could be used inside stat.inc as
>
> if (defined(gamma)!=3) gamma(x) = exp(lgamma_nat(x))
But that will always be true.
The conditional compilation is set during configuration so that you
always get a gamma function. The only question is whether you get
one from a system library or whether you get one from gnuplot's
inline code.
> then get rid of these comments like:
>
> # If you have the lgamma() function compiled into gnuplot
> As soon as someone starts uncommenting/commenting code it becomes confusing.
That comment is confusing to me already. My reading of the
code leads me to believe that gnuplot will always provide a
lgamma() function. Again there is a question of whether this
came from a system library or not. But either way you can
use the function.
> , you can use
> # alternate definitions for some PDFs. For larger arguments this will result
> # in more efficient evalution. Just uncomment the definitions containing the
> # string `lgamma', while at the same time commenting out the originals.
> # NOTE: In these cases the recursive definition for lgamma() is NOT sufficient!
>
>
>
> Last, how about an internally defined 'eps' or something similar to represent float machine precision?
>
>
> Oh, one other thing. Any interest in a complex version of the gamma function?
>
--
Ethan A Merritt
Biomolecular Structure Center
University of Washington, Seattle 98195-7742
|
|
From: Daniel J S. <dan...@ie...> - 2006-05-30 00:44:54
|
Ethan A Merritt wrote:
> On Monday 29 May 2006 03:28 pm, Daniel J Sebald wrote:
>
>>This seems like a bug, even though the syntax is incorrect... but a user might think the syntax is correct if gnuplot doesn't complain but rather returns a non-zero value that will always test positive.
>>
>>gnuplot> print defined("foo")
>>141158968
>
>
> We don't have a user-visible TBOOLEAN type,
> so any non-zero value represents "TRUE"
Right. The point is that the test and the result are meaningless. foo was never defined, so if anything the result should be zero. But this is not proper syntax. Proper syntax is
`defined(X)` returns 1 if a variable named X has been defined, otherwise
it returns 0.
so,
gnuplot> print defined(foo)
0
which is correct. However, the user could unknowingly be typing
defined("foo")
oblivious to the fact that it is meaningless.
>>Also, would it be useful to extend defined() from just variables to functions as well?
>>Say, return 1 if user defined variable, 2 if internal variable, 3 if user defined function,
>>4 if internal function.
>
>
> What would you do with this information?
Pretty much any kind of test one would do similar to checking for variables, I would guess.
> That comment is confusing to me already. My reading of the
> code leads me to believe that gnuplot will always provide a
> lgamma() function. Again there is a question of whether this
> came from a system library or not. But either way you can
> use the function.
Yes, I kind of concluded that too. Just toss the comments and make life easy. Even still, defined() on functions might have a purpose.
Dan
|
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-05-30 15:27:54
|
On Monday 29 May 2006 05:53 pm, Daniel J Sebald wrote:
> >>
> >>gnuplot> print defined("foo")
> >>141158968
> >
> > We don't have a user-visible TBOOLEAN type,
> > so any non-zero value represents "TRUE"
>
> Right. The point is that the test and the result are meaningless.
> foo was never defined, so if anything the result should be zero.
I think you are looking at this the wrong way.
The defined() operator is to protect you from trying to evaluate
an expression with an undefined quantity.
"foo" (with the quotes) is a legal string and hence a legal
token to place in an expression. So defined("foo") is TRUE.
This is no stranger than
print defined(42)
or print defined(sin(x))
or for that matter
print (4 || 2)
The problem is not in the syntax of defined(); the problem
is that you should not be trying to "print" a BOOLEAN. It would
be nicer if 'print defined(1)' resulted in printing the string
TRUE, but I don't see a way to do that.
If there is a bug lurking anywhere here, it is that
print defined(0)
results in 0 rather than 1.
--
Ethan A Merritt
Biomolecular Structure Center
University of Washington, Seattle 98195-7742
|
|
From: Daniel J S. <dan...@ie...> - 2006-05-30 16:51:17
|
Ethan A Merritt wrote:
> On Monday 29 May 2006 05:53 pm, Daniel J Sebald wrote:
>
>>>>gnuplot> print defined("foo")
>>>>141158968
>>>
>>>We don't have a user-visible TBOOLEAN type,
>>>so any non-zero value represents "TRUE"
>>
>>Right. The point is that the test and the result are meaningless.
>>foo was never defined, so if anything the result should be zero.
>
>
> I think you are looking at this the wrong way.
> The defined() operator is to protect you from trying to evaluate
> an expression with an undefined quantity.
> "foo" (with the quotes) is a legal string and hence a legal
> token to place in an expression. So defined("foo") is TRUE.
OK, I see your perspective now; that the test is if and what the hunk of ascii code means to gnuplot's parser. What exactly the utility of that is, I don't know.
>
> This is no stranger than
> print defined(42)
> or print defined(sin(x))
> or for that matter
> print (4 || 2)
I think it is stranger. I mean, 4||2 is part of the language, the math rules. Nowhere in 4||2 is there any kind of *variable*. Now reading the documentation, I see:
Subtopic of functions: defined
`defined(X)` returns 1 if a variable named X has been defined, otherwise
it returns 0.
specifically "variable named X", key word "variable".
>
> The problem is not in the syntax of defined(); the problem
> is that you should not be trying to "print" a BOOLEAN. It would
> be nicer if 'print defined(1)' resulted in printing the string
> TRUE, but I don't see a way to do that.
I actually think this should be easier; just look in the linked list for a definition matching. If it is there, the variable is defined (1), otherwise (0).
Here's how Octave behaves:
octave:2> exist("foo")
ans = 0
octave:3> foo = 23
foo = 23
octave:4> exist("foo")
ans = 1
octave:5>
Should everything behave like Octave? No, but one would think similar in concept, because afterall as in many languages gnuplot has similar concepts like x*y, sin(x)/y, etc.
>
> If there is a bug lurking anywhere here, it is that
> print defined(0)
> results in 0 rather than 1.
>
The thing is that "defined()" is currently returning the definition of something, it is not answering the question as to whether something is defined.
I say it is much more than that. I still don't see anything as to why the defined("foo") vs. defined(foo) should be any less confusing to a marginally familiar user; the programmer's perspective is different from the user's on this I think. Also, I see little utility in defined("foo") or defined(1) in light of what the gnuplot documentation says. In the same category as defined(0), there is
gnuplot> print defined(1/0)
^
undefined value
This one is funny because certainly 1/0 has meaning in gnuplot, so why doesn't "defined(1/0)" evaluate to non-zero by it's current interpretation? Or! :-) 1/0 means an undefined value, so why doesn't "defined(1/0)" return 0? Instead, it returns undefined value, which is not the same as
gnuplot> print defined(blah(x))
undefined function: blah
I'll conclude this like the discussion of a couple weeks ago... Put me in the "if it's a defined variable 1, otherwise 0" camp, for what it's worth.
Dan
|
|
From: Petr M. <mi...@ph...> - 2006-05-30 17:04:59
|
> Subtopic of functions: defined > `defined(X)` returns 1 if a variable named X has been defined, otherwise > it returns 0. I also vote for this convention. --- PM |
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-05-31 03:00:39
|
On Tuesday 30 May 2006 10:04 am, Petr Mikulik wrote: > > Subtopic of functions: defined > > `defined(X)` returns 1 if a variable named X has been defined, otherwise > > it returns 0. > > I also vote for this convention. Fine with me. Can you see how to implement it? The best I can come up so far is to give up on treating defined() as a normal function and make it a special case token in the command parser. That would work, but it feels very inelegant. -- Ethan A Merritt Biomolecular Structure Center University of Washington, Seattle 98195-7742 |
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-05-31 06:14:39
|
On Tuesday 30 May 2006 10:04 am, Petr Mikulik wrote: > > Subtopic of functions: defined > > `defined(X)` returns 1 if a variable named X has been defined, otherwise > > it returns 0. > > I also vote for this convention. OK. I found a way to make it work. Patch uploaded to SourceForge #1497957. I found one corner case that generates a strange error message on strange input, but other than that it seems OK. Please test. -- Ethan A Merritt Biomolecular Structure Center University of Washington, Seattle 98195-7742 |
|
From: Daniel J S. <dan...@ie...> - 2006-05-31 07:15:28
|
Ethan A Merritt wrote:
> On Tuesday 30 May 2006 10:04 am, Petr Mikulik wrote:
>
>>>Subtopic of functions: defined
>>>`defined(X)` returns 1 if a variable named X has been defined, otherwise
>>>it returns 0.
>>
>>I also vote for this convention.
>
>
> OK. I found a way to make it work.
> Patch uploaded to SourceForge #1497957.
> I found one corner case that generates a strange error message
> on strange input, but other than that it seems OK.
>
> Please test.
In the code is a redundant a.type = 0;
#if (1) /* Flag type a 0 because only the defined/undefined flag means anything */
a.type = 0;
if (udv->udv_undef)
a.v.int_val = 0;
else
a.v.int_val = 1;
a.type = 0; push(&a);
return;
#else
but conceptually I think it should be solid. The one issue is if somewhere an argument is passed in for which a.type was never set to INTGR CMPLX or STRINGS but neither is it a variable that had gone through PUSHV. Maybe a way to solve that would be to change:
/* type_udv() will return 0 rather than type if udv does not exist */
enum DATA_TYPES {
INTGR=1,
CMPLX
#ifdef GP_STRING_VARS
, STRING
#endif
};
to
/* type_udv() will return 0 rather than type if udv does not exist */
enum DATA_TYPES {
INTGR=1,
CMPLX,
BOOLVAR
#ifdef GP_STRING_VARS
, STRING
#endif
};
then it would be a.type = BOOLVAR and
if (a.type == BOOLVAR)
push(Ginteger(&a, a.v.int_val));
else
push(Ginteger(&a, 0));
[Maybe put an assert() in there to check if ever .type is zero.]
Or is that abusing the DATA_TYPES too much?
...
I see it is possible to have a function and variable of the same name. I'm OK with that, but this seems a little strange, in that it would bewilder a beginning programmer. :-)
gnuplot> cos = 5
gnuplot> print cos(cos)
0.283662185463226
gnuplot>
Dan
|
|
From: Daniel J S. <dan...@ie...> - 2006-05-31 08:26:39
|
Daniel J Sebald wrote:
> /* type_udv() will return 0 rather than type if udv does not exist */
> enum DATA_TYPES {
> INTGR=1,
> CMPLX
> #ifdef GP_STRING_VARS
> , STRING
> #endif
> };
And if you want to make the STRING data type permanent, in the f_isvar() it would be pretty easy to check for the string in the udv linked list (I think the routine already exists) and make
defined(foo)
defined("foo")
behave the same.
Dan
|
|
From: Ethan A M. <merritt@u.washington.edu> - 2006-05-31 15:20:25
|
On Wednesday 31 May 2006 12:24 am, you wrote: > > In the code is a redundant a.type = 0; Noted. It's a debugging patch, not a final version. > The one issue is if somewhere an argument is passed in for > which a.type was never set to INTGR CMPLX or STRINGS but > neither is it a variable that had gone through PUSHV. That cannot happen. The expression evaluation code screams loudly if any type other than those 3 is set. > Is this the strange case you are talking about? > gnuplot> print defined(cos(x)) > unknown type in real() Yeah. That is what happens if a type other than INTGR/CMPLX/STRING makes it through to the expression evaluation code. > [proposal to add BOOLVAR as an enum DATA_TYPE The problem with this is that it requires changing every single routine in the expression evaluation chain, or at least confirming that a correct default case has been set. I had to do this when I added the STRING type, and it's a pain. > I see it is possible to have a function and variable of the same name. That has always been true. I don't think we can change it now without eliciting complaints from HBB about breaking backwards compatibility :-) -- Ethan A Merritt Biomolecular Structure Center University of Washington, Seattle 98195-7742 |
|
From: Daniel J S. <dan...@ie...> - 2006-05-31 09:05:32
|
Ethan A Merritt wrote:
> On Tuesday 30 May 2006 10:04 am, Petr Mikulik wrote:
>
>>>Subtopic of functions: defined
>>>`defined(X)` returns 1 if a variable named X has been defined, otherwise
>>>it returns 0.
>>
>>I also vote for this convention.
>
>
> OK. I found a way to make it work.
> Patch uploaded to SourceForge #1497957.
> I found one corner case that generates a strange error message
> on strange input, but other than that it seems OK.
>
> Please test.
Is this the strange case you are talking about?
gnuplot> print defined(cos(x))
unknown type in real()
gnuplot> y = 2
gnuplot> print defined(cos(y))
unknown type in real()
gnuplot> print defined(cos(pi))
unknown type in real()
|