-
Notifications
You must be signed in to change notification settings - Fork 165
Description
Currently Moodle Stack units are Blocks that can only under specific circumstances interact with normal math operations which is quite counterintuitive. For example:
stackunits(2,m) * stackunits(3,m)
will not equate to 6 m^2. I am unaware of how well one can overload or edit the functions of maxima but i have a set of maxima functions that one can use to solve this problem. The are briefly tested but might still have some bugs in them:
stack_unit_si_declare(true)$
su(x,y) := stackunits(x,y)$
b(x) := stack_unit_si_to_si_base(x)$
bf(x) := ev(stack_unit_si_to_si_base(x), NULLUNITS=1)$
u(x) := ev(stack_units_units(x), NULLUNITS=1)$
ua(x) := stack_units_units(x)$
v(x) := stack_units_nums(x)$
numer(x) := ev(x, numer)$
to_su(x) := block([nun:emptyp(listofunits(x))], if nun then su(numer(x),1) else x)$
uadd(x,y) := block([Xb:b(x),Yb:b(y)], if is(ua(Xb)=ua(Yb)) then su(numer(ratsimp(v(Xb)+v(Yb))),ua(Xb)) else su(numer(v(Xb)),ua(Xb))+su(numer(v(Yb)),ua(Yb)))$
usub(x,y) := uadd(x, -y)$
usum(L) := block([acc:first(L)], for z in rest(L) do acc:uadd(acc,z), acc)$
umult(x,y) := b(su(numer(ratsimp(v(b(x))*v(b(y)))), ratsimp(u(b(x))*u(b(y)))))$
uprod(L) := block([acc:first(L)], for z in rest(L) do acc:umult(acc,z), acc)$
upow(x,p) := b(su(numer(v(b(x))^p), block([assume_pos:true], ratsimp(u(b(x))^p))))$
usqrt(x) := upow(x,1/2)$
udiv(x, y) := umult(x, upow(y, -1))$
uabs(x) := b(su(numer(abs(v(x))), u(x)))$
usin(x) := sin(b(x))
ucos(x) := cos(b(x))
utan(x) := tan(b(x))
round_decimals_u(x,n) := block([X:to_su(x),k:10^n], su(numer(round(float(v(X))*k)/k), u(X)))$
round_sig_u(x,s) := block([X:to_su(x),a:abs(float(v(X)))], if a=0 then su(0.0,u(X)) else block([e:floor(log10(a)),k:10^(s-1-e)], su(numer(round(v(X)*k)/k),u(X))))$
And here are some testcases that ran through using these functions:
\( 3\text{m} + 4\text{m} = {@ uadd( su(3,m), su(4,m) ) @} \) ( \( 7 \text{m} \) )
\( 400\text{m} + 1\text{km} = {@ uadd( su(400,m), su(1,km) ) @} \) ( \( 1400 \text{m} \) )
\( 3\text{m} + 4\text{s} = {@ uadd( su(3,m), su(4,s) ) @} \) ( \( 3\text{m} + 4\text{s} \) )
\( 3\text{m} + 0\text{m} = {@ uadd( su(3,m), su(0,m) ) @} \) ( \( 3\text{m} \) )
\( 3\text{m} + 0\text{s} = {@ uadd( su(3,m), su(0,s) ) @} \) ( \( 3\text{m} + 0\text{s} \) )
\( 3\text{m} + 4 = {@ uadd( su(3,m), 4 ) @} \) ( \( 3\text{m} + 4 \) )
\( 3\text{m} + 0 = {@ uadd( su(3,m), 0 ) @} \) ( \( 3\text{m} \) )
\( 3\text{1} + 4 = {@ uadd( su(3,1), 4 ) @} \) ( \( 7 \) )
\( 3 + 4 = {@ uadd( 3, 4 ) @} \) ( \( 7 \) )
\( 3 + 0 = {@ uadd( 3, 0 ) @} \) ( \( 3 \) )
\( 3 + (-4) = {@ uadd( 3, -4 ) @} \) ( \( -1 \) )
\( 3\text{m} + (-4\text{m}) = {@ uadd( su(3,m), su(-4,m) ) @} \) ( \( - 1\text{m} \) )
\( 1 + 2 + 3 + 4 = {@ usum([1,2, 3, 4]) @} \) ( \( 10 \) )
\( 1\text{m} + 2\text{m} + 3\text{s} + 4\text{s} = {@ usum([su(1,m),su(2,m), su(3,s), su(4,s)]) @} \) ( \( 3\text{m} + 7\text{s}\) )
\( 3\text{m} \cdot 3\text{s} = {@ umult( su(3,m), su(3,s) ) @} \) ( \( 9\text{ms} \) )
\( 3\text{m} \cdot 1\text{km} = {@ umult( su(3,m), su(1,km) ) @} \) ( \( 3000\text{m}^2 \) )
\( 3\text{m} \cdot 0\text{m} = {@ umult( su(3,m), su(0,m) ) @} \) ( \( 0 \) )
\( 3\text{m} \cdot 3\mathbf{1} = {@ umult( su(3,m), su(3,1) ) @} \) ( \( 9\text{m} \) )
\( 3\text{m} \cdot 3 = {@ umult( su(3,m), 3 ) @} \) ( \( 9\text{m} \) )
\( 3\mathbf{1} \cdot 2 = {@ umult( su(3,1), 2 ) @} \) ( \( 6 \) )
\( 3 \cdot 0\mathbf{1} = {@ umult( 3, su(0,1) ) @} \) ( \( 0 \) )
\( 3 \cdot 2 = {@ umult( 3, 2 ) @} \) ( \( 6 \) )
\( 3 \cdot 0 = {@ umult( 3, 0 ) @} \) ( \( 0 \) )
\( 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 = {@ uprod([1, 2, 3, 4, 5]) @} \) ( \( 120 \) )
\( \frac{2\text{m}}{2\text{m}} = {@ udiv( su(2,m), su(2,m) ) @} \) ( \( 1 \) )
\( \frac{1}{5\text{s}} = {@ udiv( 1, su(5,s) ) @} \) ( \( 0.2 \frac{1}{s} \) )
\( (5\text{s})^2 = {@ upow( su(5,s), 2 ) @} \) ( \( 25\text{s}^2 \) )
\( (5\text{s})^{-1} = {@ upow( su(5,s), -1 ) @} \) ( \( 0.2 \frac{1}{s} \) )
\( \sqrt{\,25\text{s}^2\,} = {@ usqrt( su(25, s^2) ) @} \) ( \( 5\text{s} \) )
\( \left| -5\text{m} \right| = {@ uabs( su(-5,m) ) @} \) ( \( 5\text{m} \) )
\( \left| -5 \right| = {@ uabs( -5 ) @} \) ( \( 5 \) )
\( \sin(2) = {@ usin( 2 ) @} \) ( \( 0.909 \) )
\( \sin(2\cdot \mathbf{1}) = {@ usin( su(2,1) ) @} \) ( \( 0.909 \) )
\( \sin(3\text{m}) = {@ usin( su(3,m) ) @} \) ( \( \sin(3\text{m}) \) )
\( \cos(2) = {@ ucos( 2 ) @} \) ( \( -0.416 \) )
\( \cos(2\cdot \mathbf{1}) = {@ ucos( su(2,1) ) @} \) ( \( -0.416 \) )
\( \cos(3\text{m}) = {@ ucos( su(3,m) ) @} \) ( \( \cos(3\text{m}) \) )
\( \tan(2) = {@ utan( 2 ) @} \) ( \( -2.185 \) )
\( \tan(2\cdot \mathbf{1}) = {@ utan( su(2,1) ) @} \) ( \( -2.185 \) )
\( \tan(3\text{m}) = {@ utan( su(3,m) ) @} \) ( \( \tan(3\text{m}) \) )and the results:
Maybe there is a way to implement this directly into the maxima operators so the behavior of stack units is more intuitive. Hope this can be of any help.
P.S. I just realized, not all tests are successful e.g. the usum does not follow commutative law which will need to be thought thrrough a lot more then i did while throwing together these simple functions