WeBWorK Problems

development sources, Function 'norm' has too few inputs

by Andy Fuchs -
Number of replies: 5
Hi,

We've run into the following (non-critical) inconsistency in computations involving cross products in the development branch of PG (1dd61f3). The code in question runs without problems under 2.11.

Having defined vectors $a,$b, $c and$d = ($a -$b) x $c, we are able to compute norm($d) while norm(($a -$b) x $c) fails with an error of "Function 'norm' has too few inputs". At the same time, we are able to evaluate expressions like 'norm($a - $b)' , 'norm($a x $b)' and the formally similar 'norm($a x ($b -$c))'. Thus, while 'norm(($a -$b) x $c)' fails, the equivalent 'norm($c->cross($a-$b))' involving the cross method, and the algebraically equivalent 'norm(($a x$c) - ($b x$c))' compile without problems.

Any thoughts? The above makes reference to the code below.

Many thanks!

Andy

#######
DOCUMENT();

"PGstandard.pl",
"MathObjects.pl",
);

TEXT(beginproblem());

Context("Vector");

$a = Vector([1,2,3]);$b = Vector([4,5,6]);
$c = Vector([1,1,0]);$d = ($a -$b) x $c; #$e = norm($d);$e = norm(($a -$b) x $c); #$e = norm(($a x$c) - ($b x$c));
#$e = norm(($a - $b)->cross($c));
#$f = norm($a x ($b -$c));

BEGIN_TEXT
$$d = d$$ and $$e = e$$
END_TEXT

ENDDOCUMENT();

In reply to Andy Fuchs

Re: development sources, Function 'norm' has too few inputs

by Davide Cervone -
OK, here's what's going on. MathObjects uses the perl overload extension in order to make the various perl operators work on the MathObject classes. So the perl x operator is overloaded to work with Vector objects. The usual perl x is used to make repeated strings or repeated elements in an array. So
"a" x 10

produces a string of 10 a's, while
(0) x 10

produces an array of 10 zeros. It is the presence of the parentheses that distinguishes the two.

($a -$b) x $c  looks like the array form, and that is what is causing the problem. Subroutines in perl usually take an array or arguments, so norm(($a - $b) x$c)

looks to perl like a function call on an array of a repeated element. But because $c is not a number, it appears that perl treats it like a zero, and produces an empty list, which is passed to norm(), giving you the error message you are seeing. On the other hand, $d = ($a -$b) x $c;  assigns the value to $d, which is a "scalar" quantity ($d is a pointer to an object, which is a scalar in perl, even though it points to an object that implements a vector). So the ($a - $b) x$c is evaluated in "scalar context" instead of "array context", and so it doesn't produce an array, it does the normal x, which MathObjects has overridden. So that works normally. But in norm(($a -$b) x $c), the expression is in array context, and so produces the empty array. I don't see a way to overload the array version of x, so I don't think I can fix this behavior. On the other hand, there are several workarounds, like the ones you have given. There is also (the confusing looking) $e = norm(scalar(($a -$b) x $c));  or you could define an alternative function with a template so that it knows that there should be only one scalar argument: sub Norm ($) {norm(@_)}

$e = Norm(($a - $b) x$c);

I suppose the definition for norm() could be fixed to have the template, but that would mean the other functions should also have templates. It might take a bit of care to get that right.

In any case, I think that should explain what is going on.

In reply to Davide Cervone

Re: development sources, Function 'norm' has too few inputs

by Andy Fuchs -
Excellent analysis!

Again, it isn't critical--and easy enough to work with.

Thanks very much for the detailed explanation,

A

In reply to Andy Fuchs

Re: development sources, Function 'norm' has too few inputs

by Peter Selinger -
I have added a brief summary of this issue to the documentation at

http://webwork.maa.org/wiki/Vector_(MathObject_Class)

Maybe another possible workaround would be to add an operator 'crossprod', as an alternative to 'x'? It could then be used in situations where the overloading of 'x' causes problems.

By the way, does Perl/WebWork support Unicode? As we are living in a Unicode world, perhaps the symbol '×' (U+00D7) could also be supported, in Perl and/or for user input, as another alternative for 'x'.
In reply to Peter Selinger

Re: development sources, Function 'norm' has too few inputs

by Davide Cervone -
another possible workaround would be to add an operator 'crossprod', as an alternative to 'x'?

I don't think it is possible to add operators to perl itself (as far as I know, you can only overload existing ones). But there are ways to call methods that are non-standard, so cross $a$b is the same as $a->cross($b), but these don't seem to interact with parentheses well, either: cross ($a-$b) $c treats this as a function call for (an undefined) cross() function, and expects an operator between cross($a-$b) and $c.

So I don't think that what you ask can be done for PG programs directly.

As for the Unicode input, I think there is work being done to support unicode within WeBWorK, and once the is done, you should be able to add U+00D7 to the operators in the context to enable that for user input. But I just checked and that doesn't yet work in the current release version of WeBWorK.
In reply to Peter Selinger

Re: development sources, Function 'norm' has too few inputs

by Michael Gage -
Thanks Peter for adding to the permanent documentation. That's a big help and we don't get around to updating documentation as much as we should. The Unicode support is being developed and is currently sitting as pull requests to the develop branch of WeBWorK. We are going somewhat slowly in adding the unicode support because while the change is small it is pervasive and has a real chance of not being backward compatible. As a result we are being cautious and not trying to take any action that might raise issues that we wouldn't have the man-hours to fix quickly.

If you have the capability of temporarily trying out some of the utf8 patches and reviewing them let me know.