/* ezunits: yet another units package for Maxima
 * This program copyright 2008 by Robert Dodier.
 * I release this program under the terms of the
 * GNU General Public License.
 */

(kill (all), load (ezunits), 0);
0;

a`m^3;
a`(m^3);

(a`m)^3;
(a^3)`(m^3);

%pi/a`m;
(%pi/a)`m;

%pi/(a`m);
(%pi/a)`(1/m);

unit_kg: 1`kg;
1`kg;

50*unit_kg;
50`kg;

%pi*(a`m);
%pi*a`m;

a*b`m*kg;
(a*b)`(m*kg);

a/b`m/kg;
(a/b)`(m/kg);

a`m + b`m;
(a + b)`m;

a`m - b`m;
(a - b)`m;

a`m - a`m;
0`m;

a`m + b`kg;
(a`m) + (b`kg);

(a`m)*(b`m);
(a*b)`(m^2);

(a`m)/(b`kg);
(a/b)`(m/kg);

(a`m)*(b`m)*(c`m);
(a*b*c)`(m^3);

(a`m)*exp(sin(z))*(b`m);
(exp(sin(z))*a*b)`(m^2);

(a`m)/(b`s)/(c`kg);
(a/(b*c))`(m/(s*kg));

(a`m)/((b`s)*(c`kg));
(a/(b*c))`(m/(s*kg));

a`m + b`m + c`m;
(a + b + c)`m;

(a`m)*(b`m)*(c`m)*(d`m);
a*b*c*d`m^4;

/* begin addt'l stuff adapted from Cliff Yapp's email
 * to the Maxima mailing list 2005/05/21.
 */
a`s + c;
(a`s) + c;

a + c`s;
a + (c`s);

a`kg/s + c;
(a`(kg/s)) + c;

a`kg/s + c`kg/s;
(a + c)`(kg/s);

a`kg/s - c`kg/s + d`kg/s;
(a - c + d)`kg/s;

a`kg*m/s^2 + c;
(a`(kg*m/s^2)) + c;

a`kg*m/s^2 + c`kg*m/s^2;
(a + c)`(kg*m/s^2);

a`kg*m/s^2 + c`kg*m/s^2 - d`kg*m/s^2;
(a + c - d)`(kg*m/s^2);

a`kg/s + c`kg/s + d`kg*m/s^2;
(a + c)`(kg/s) + d`(kg*m/s^2);

a`kg/s + c`kg*m/s^2 + d`kg*m/s^2;
a`kg/s + (c + d)`kg*m/s^2;

(N: kg*m/s^2, 0);
0;

(J: N*m, 0);
0;

a`kg/s + b`N + c`kg/s + d`N + e`kg/s;
(a + c + e)`kg/s + (b + d)`kg*m/s^2;

1/60`kg/s + a`kg/s + b`kg/s + c`kg/s^2 + d`kg/s^2;
(1/60 + a + b)`kg/s + (c + d)`kg/s^2;

a/60`kg/s + a`kg/s + b`kg/s + c`kg/s^2 + d`kg/s^2;
(a/60 + a + b)`kg/s + (c + d)`kg/s^2;

(a/60)`kg/s + a*b`kg/s;
(a/60 + a*b)`kg/s;

a`kg*m/s^2 + b`N*J + c`kg/s + d`N*J - e`kg*m/s^2;
(a - e)`kg*m/s^2 + c`kg/s + (b + d)`kg^2*m^3/s^4;

sin(1`s);
sin(1`s);

-1`1/s;
-1`1/s;

sin(1`kg/s);
sin(1`kg/s);
/* end stuff adapted from Cliff Yapp's email
 */

(kill (J, N), 0);
0;

/* foo(a`s) fails nondimensional_not1 test, due to presence of a`s within.
 * => No rule triggered here.
 */
(a`b)*(c`d)*foo(e`f);
''(block ([simp: false], (a`b)*(c`d)*foo(e`f)));

(F: C*(5/9) + 32, 0);
0;

212`F;
100`C;

32`F;
0`C;

-40`F;
-40`C;

deg: rad*%pi/180;
rad*%pi/180;

90`deg;
%pi/2`rad;

a`%pi;
a*%pi;

sin(135`deg);
sin(3*%pi/4`rad);

sin(135`deg), rad=1;
sqrt(2)/2;

(declare ([C1, C2], constant), 0);
0;

/* Constants for Planck's law */
[declare_constvalue (%C2, 14390.0), declare_constvalue (%C1, 3.742E+8)];
[14390.0, 3.742E+8];

declare ("µ", alphabetic);
done;

(C1: %C1`W*µm^4/m^2, C2: %C2`µm*K, l: %l`µm, T: %T`K, 0);
0;

/* "infeval=true" is a work-around for simplification strangeness:
 * after load("units.mac")$ kill(all)$ load("units.mac")$
 * the simplifier doesn't try so hard to use tellsimpafter rules,
 * but it can be coaxed by re-evaluation via ''expr or infeval=true.
 */
expr: C1/(l^5*(exp(C2/(l*T)) - 1)), infeval=true;
%C1/(%l^5*(%e^(%C2/(%l*%T))-1)) ` W/(m^2*µm);

ev (expr, constvalue);
3.742E+8/(%l^5*(%e^(14390.0/(%l*%T))-1)) ` W/(m^2*µm);

qty(%), %T=6000;
3.742E+8 / (%l^5 * (%e^(2.398333333333333/%l) - 1));

/* Now try this -- should yield a skewed bump.
 * plot2d (%, [%l, 0.05, 3]);
 */

declare ([a1, b1, c1], dimensional);
done;

a1 + b1 + c1;
'qty(a1)`'units(a1) + 'qty(b1)`'units(b1) + 'qty(c1)`'units(c1);

declare_units ('[a1, b1, c1], mph);
mph;

a1: 50`mph;
50`mph;

catch (b1: 50`gpf);
oops ('b1, 50`gpf);

b1: c1;
c1;

a1 + b1 + c1, infeval;
2*c1 + 50`mph;

(declare_qty ('a1, 100), declare_qty ('b1, 200), declare_qty ('c1, 300));
300;

a1 + b1 + c1, infeval;
650`mph;

c1 + 1000`mph;
1300`mph;

c1 + 1000`kg;
300`mph + 1000`kg;

(a1 + 500`mph)/(b1 - 100`mph), infeval;
11/4;

map (declare_units, [aa, bb, cc, dd, ee, ff, gg], [m, kg, s, K, feet, in, acre]);
[m, kg, s, K, feet, in, acre];

catch (aa: bb);
oops ('aa, bb);

catch (bb: aa);
oops ('bb, aa);

catch (cc: a1);
''(oops ('cc, a1));

catch (apply (lambda ([ff], cc^2), [gg]));
oops ('ff, gg);

units (aa*bb*cc*dd*ee*ff*gg);
m*kg*s*K*feet*in*acre;

[aa: %aa`m, bb: %bb`kg, cc: %cc`s, dd: %dd`K, ee: %ee`feet, ff: %ff`in, gg: %gg`acre];
[%aa`m, %bb`kg, %cc`s, %dd`K, %ee`feet, %ff`in, %gg`acre];

ff: ee*(12`in)/(1`feet);
12*%ee`in;

gg: ff^2*((1`yd)/(36`in))^2*(1`acre)/(55*88`yd^2);
%ee^2/43560`acre;

declare_units (foo, m/s^2);
m/s^2;

units (foo (p, q));
m/s^2;

qty (foo (p, q));
'qty (foo (p, q));

aa: foo (p, q) * cc * (100`s);
100 * qty (foo (p, q)) * %cc ` m;

declare_units (bar, kg/acre);
kg/acre;

bb: bar[n] * gg;
''(qty(bar[n]) * qty(gg) ` kg);

catch (cc: bar[k]);
oops ('cc, bar[k]);

cc: bar[11] * (57 ` s/kg) * (10 ` acre);
570 * qty(bar[11]) ` s;

/* Unit conversions */

100 ` degC `` degF;
212 ` degF;

-40 ` degF `` degC;
-40 ` degC;

1 ` acre*ft `` m^3;
60228605349/48828125 ` m^3;

/* Stefan-Boltzmann constant */
56697/10000/10^8 ` W/m^2/K^4 `` Btu/h/ft^2/R^4;
304821971/178031250000000000 ` Btu/h/ft^2/R^4;

declare_unit_conversion (MMBtu = 10^6*Btu, kW = 1000*W, kWh = kW*h, MWh = 1000*kWh);
done;

1 ` MMBtu `` MWh;
211/720 ` MWh;

1 ` MMBtu/d `` kW;
5275/432 ` kW;

(load (physical_constants), 0);
0;

map (lambda ([x], featurep (x, physical_constant)), [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
[true, true, true, true, true, true, true];

map (constantp, [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
[true, true, true, true, true, true, true];

map (units, [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
''([m/s, N/A^2, s^2*A^2/(m^2*N), m*N/(s*A^2), m^3/(kg*s^2), J*s, J*s]);

map (dimensions, [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
[length/time,
 length*mass/(charge^2*time^2),
 charge^2*time^4/(length^3*mass),
 length^2*mass/(charge^2*time^3),
 length^3/(mass*time^2),
 length^2*mass/time,
 length^2*mass/time];

fundamental_dimensions;
[length, mass, time, charge, temperature, quantity];

map (dimensions_as_list, [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
[[1, 0, - 1, 0, 0, 0],
 [1, 1, - 2, - 2, 0, 0],
 [- 3, - 1, 4, 2, 0, 0],
 [2, 1, - 3, - 2, 0, 0],
 [3, - 1, - 2, 0, 0, 0],
 [2, 1, - 1, 0, 0, 0],
 [2, 1, - 1, 0, 0, 0]];

map (fundamental_units, [%c, %mu_0, %e_0, %Z_0, %G, %h, %h_bar]);
[m/s,
 kg*m/(s^2*A^2),
 s^4*A^2/(kg*m^3),
 kg*m^2/(s^3*A^2),
 m^3/(kg*s^2),
 kg*m^2/s,
 kg*m^2/s];

/* examples from message from ed romana to mailing list 2007-12-02, -12-03 */

e : 1/sqrt (%mu_0 * %e_0);
1/sqrt (%mu_0 * %e_0);

[e, %c], constvalue;
[299792458 ` m/s, 299792458 ` m/s];

/* Helium sound velocity at 27 C, He(Cp/Cv)=5/3, 4gr/mol */
e : sqrt (5/3 * %R/(4 ` g/mol) * (27 ` degC `` K));
sqrt(2001)*sqrt(%R)/4 ` sqrt(mol)*sqrt(K)/sqrt(g);

dimensions (e);
length / time;

e : constvalue (e);
sqrt(2001)*sqrt(1039309)/(1000*sqrt(2)) ` sqrt(J)/sqrt(g);

dimensions (e);
length / time;

u : fundamental_units (e);
m/s;

e : e `` u;
sqrt(2001)*sqrt(1039309)*%e^(log(1000)/2)/(1000*sqrt(2)) ` m/s;

e, numer;
1019.719890214955 ` m/s;
