mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Merge pull request #434 from ericman314/units-extra-fxns
Added support for units to abs, cube, sign, sqrt, square
This commit is contained in:
commit
df9270a67f
@ -88,9 +88,8 @@ var incorrect = math.unit('8.314 m^3 Pa / mol K'); // Unit 8.314 (m^3 P
|
||||
|
||||
## Calculations
|
||||
|
||||
Basic operations `add`, `subtract`, `multiply`, `divide`, and `pow` can be performed
|
||||
on units. Trigonometric functions like `sin` support units with an angle as
|
||||
argument.
|
||||
The operations that support units are `add`, `subtract`, `multiply`, `divide`, `pow`, `abs`, `sqrt`, `square`, `cube`, and `sign`.
|
||||
Trigonometric functions like `cos` are also supported when the argument is an angle.
|
||||
|
||||
```js
|
||||
var a = math.unit(45, 'cm'); // Unit 450 mm
|
||||
@ -119,6 +118,22 @@ var q = math.eval('1 C'); // 1 C
|
||||
var F = math.multiply(q, math.cross(v, B)); // [0 N, 0 N, -1 N]
|
||||
```
|
||||
|
||||
All arithmetic operators act on the value of the unit as it is represented in SI units.
|
||||
This may lead to surprising behavior when working with temperature scales like `celsius` (or `degC`) and `fahrenheit` (or `degF`).
|
||||
In general you should avoid calculations using `celsius` and `fahrenheit`. Rather, use `kelvin` (or `K`) and `rankine` (or `R`) instead.
|
||||
This example highlights some problems when using `celsius` and `fahrenheit` in calculations:
|
||||
|
||||
```js
|
||||
var T_14F = math.unit('14 degF'); // Unit 14 degF (263.15 K)
|
||||
var T_28F = math.multiply(T1, 2); // Unit 487.67 degF (526.3 K), not 28 degF
|
||||
|
||||
var Tnegative = math.unit(-13, 'degF'); // Unit -13 degF (248.15 K)
|
||||
var Tpositive = math.abs(T1); // Unit -13 degF (248.15 K), not 13 degF
|
||||
|
||||
var Trate1 = math.eval('5 (degC/hour)'); // Unit 5 degC/hour
|
||||
var Trate2 = math.eval('(5 degC)/hour'); // Unit 278.15 degC/hour
|
||||
```
|
||||
|
||||
The expression parser supports units too. This is described in the section about
|
||||
units on the page [Syntax](../expressions/syntax.md#units).
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ console.log();
|
||||
console.log('compute speed of fluid flowing out of hole in a container');
|
||||
var g = math.unit('9.81 m / s^2');
|
||||
var h = math.unit('1 m');
|
||||
var v = math.pow(math.multiply(2, math.multiply(g, h)), 0.5);
|
||||
var v = math.pow(math.multiply(2, math.multiply(g, h)), 0.5); // Can also use math.sqrt
|
||||
console.log('g = ' + format(g));
|
||||
console.log('h = ' + format(h));
|
||||
console.log('v = (2 g h) ^ 0.5 = ' + format(v)); // 4.429... m / s
|
||||
|
||||
@ -22,9 +22,9 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* sign
|
||||
*
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix} x
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
|
||||
* A number or matrix for which to get the absolute value
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix}
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}
|
||||
* Absolute value of `x`
|
||||
*/
|
||||
var abs = typed('abs', {
|
||||
@ -60,6 +60,14 @@ function factory (type, config, load, typed) {
|
||||
'Array | Matrix': function (x) {
|
||||
// deep map collection, skip zeros since abs(0) = 0
|
||||
return deepMap(x, abs, true);
|
||||
},
|
||||
|
||||
'Unit': function(x) {
|
||||
// This gives correct, but unexpected, results for units with an offset.
|
||||
// For example, abs(-283.15 degC) = -263.15 degC !!!
|
||||
var ret = x.clone();
|
||||
ret.value = Math.abs(ret.value);
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -26,8 +26,8 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* multiply, square, pow
|
||||
*
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix} x Number for which to calculate the cube
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix} Cube of x
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x Number for which to calculate the cube
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} Cube of x
|
||||
*/
|
||||
var cube = typed('cube', {
|
||||
'number': function (x) {
|
||||
@ -49,6 +49,10 @@ function factory (type, config, load, typed) {
|
||||
'Array | Matrix': function (x) {
|
||||
// deep map collection, skip zeros since cube(0) = 0
|
||||
return deepMap(x, cube, true);
|
||||
},
|
||||
|
||||
'Unit': function(x) {
|
||||
return x.pow(3);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -29,9 +29,9 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* abs
|
||||
*
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix} x
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
|
||||
* The number for which to determine the sign
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix}e
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}e
|
||||
* The sign of `x`
|
||||
*/
|
||||
var sign = typed('sign', {
|
||||
@ -53,6 +53,10 @@ function factory (type, config, load, typed) {
|
||||
'Array | Matrix': function (x) {
|
||||
// deep map collection, skip zeros since sign(0) = 0
|
||||
return deepMap(x, sign, true);
|
||||
},
|
||||
|
||||
'Unit': function(x) {
|
||||
return number.sign(x.value);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -22,9 +22,9 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* square, multiply
|
||||
*
|
||||
* @param {number | BigNumber | Complex | Array | Matrix} x
|
||||
* @param {number | BigNumber | Complex | Array | Matrix | Unit} x
|
||||
* Value for which to calculate the square root.
|
||||
* @return {number | BigNumber | Complex | Array | Matrix}
|
||||
* @return {number | BigNumber | Complex | Array | Matrix | Unit}
|
||||
* Returns the square root of `x`
|
||||
*/
|
||||
var sqrt = typed('sqrt', {
|
||||
@ -45,7 +45,13 @@ function factory (type, config, load, typed) {
|
||||
'Array | Matrix': function (x) {
|
||||
// deep map collection, skip zeros since sqrt(0) = 0
|
||||
return deepMap(x, sqrt, true);
|
||||
},
|
||||
|
||||
'Unit': function (x) {
|
||||
// Someday will work for complex units when they are implemented
|
||||
return x.pow(0.5);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -24,9 +24,9 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* multiply, cube, sqrt, pow
|
||||
*
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix} x
|
||||
* @param {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
|
||||
* Number for which to calculate the square
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix}
|
||||
* @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}
|
||||
* Squared value
|
||||
*/
|
||||
var square = typed('square', {
|
||||
@ -52,6 +52,10 @@ function factory (type, config, load, typed) {
|
||||
'Array | Matrix': function (x) {
|
||||
// deep map collection, skip zeros since square(0) = 0
|
||||
return deepMap(x, square, true);
|
||||
},
|
||||
|
||||
'Unit': function(x) {
|
||||
return x.pow(2);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -69,10 +69,13 @@ describe('abs', function () {
|
||||
assert.deepEqual(a1.valueOf(), [2,1,0,1,2])
|
||||
});
|
||||
|
||||
it('should throw an error with a measurment unit', function () {
|
||||
assert.throws(function () {
|
||||
math.abs(math.unit(5, 'km'));
|
||||
});
|
||||
it('should return the absolute value of a unit', function () {
|
||||
var u = math.abs(math.unit('5 m'));
|
||||
assert.equal(u.toString(), '5 m');
|
||||
u = math.abs(math.unit('-5 m'));
|
||||
assert.equal(u.toString(), '5 m');
|
||||
u = math.abs(math.unit('-283.15 degC'));
|
||||
assert.equal(u.toString(), '-263.15 degC');
|
||||
});
|
||||
|
||||
it('should throw an error in case of invalid number of arguments', function() {
|
||||
@ -86,8 +89,8 @@ describe('abs', function () {
|
||||
});
|
||||
|
||||
it('should LaTeX abs', function () {
|
||||
var expression = math.parse('abs(-1)');
|
||||
assert.equal(expression.toTex(),'\\left|-1\\right|');
|
||||
var expression = math.parse('abs(-1)');
|
||||
assert.equal(expression.toTex(),'\\left|-1\\right|');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -43,12 +43,14 @@ describe('cube', function() {
|
||||
assert.deepEqual(cube(math.complex('2')), math.complex('8'));
|
||||
});
|
||||
|
||||
it('should throw an error with strings', function() {
|
||||
assert.throws(function () {cube('text')});
|
||||
it('should return the cube of a unit', function() {
|
||||
assert.equal(cube(math.unit('4 cm')).toString(), '64 cm^3');
|
||||
assert.equal(cube(math.unit('-2 cm')).toString(), '-8 cm^3');
|
||||
assert.equal(cube(math.unit('0 cm')).toString(), '0 cm^3');
|
||||
});
|
||||
|
||||
it('should throw an error with units', function() {
|
||||
assert.throws(function () {cube(unit('5cm'))});
|
||||
it('should throw an error with strings', function() {
|
||||
assert.throws(function () {cube('text')});
|
||||
});
|
||||
|
||||
it('should throw an error if there\'s wrong number of args', function() {
|
||||
|
||||
@ -39,8 +39,13 @@ describe('sign', function() {
|
||||
approx.deepEqual(math.sign(math.complex(2,-3)), math.complex(0.554700196225229, -0.832050294337844));
|
||||
});
|
||||
|
||||
it('should throw an error when used with a unit', function() {
|
||||
assert.throws(function () { math.sign(math.unit('5cm')); });
|
||||
it('should calculate the sign of a unit', function() {
|
||||
assert.equal(math.sign(math.unit('5 cm')), 1);
|
||||
assert.equal(math.sign(math.unit('-5 kg')), -1);
|
||||
assert.equal(math.sign(math.unit('0 mol/s')), 0);
|
||||
assert.equal(math.sign(math.unit('-283.15 degC')), -1);
|
||||
assert.equal(math.sign(math.unit('-273.15 degC')), 0);
|
||||
assert.equal(math.sign(math.unit('-263.15 degC')), 1);
|
||||
});
|
||||
|
||||
it('should throw an error when used with a string', function() {
|
||||
|
||||
@ -64,10 +64,14 @@ describe('sqrt', function() {
|
||||
assert.deepEqual(sqrt(math.complex(1e10, 1e-10)), math.complex(1e5, 5e-16));
|
||||
});
|
||||
|
||||
it('should throw an error when used with a unit', function() {
|
||||
assert.throws(function () {
|
||||
sqrt(math.unit(5, 'km'));
|
||||
});
|
||||
it('should return the square root of a unit', function() {
|
||||
assert.equal(sqrt(math.unit('25 m^2/s^2')).toString(), '5 m / s');
|
||||
assert.equal(sqrt(math.unit('4 kg')).toString(), '2 kg^0.5');
|
||||
});
|
||||
|
||||
it('should return NaN when computing the square root of a negative unit', function() {
|
||||
// Update this when support for complex units is added
|
||||
assert.equal(sqrt(math.unit('-25 m^2/s^2')).toString(), 'NaN m / s');
|
||||
});
|
||||
|
||||
it('should throw an error when used with a string', function() {
|
||||
|
||||
@ -48,8 +48,10 @@ describe('square', function() {
|
||||
assert.deepEqual(square(math.complex('2')), math.complex('4'));
|
||||
});
|
||||
|
||||
it('should throw an error when used with a unit', function() {
|
||||
assert.throws(function () {square(unit('5cm'))});
|
||||
it('should return the square of a unit', function() {
|
||||
assert.equal(square(math.unit('4 cm')).toString(), '16 cm^2');
|
||||
assert.equal(square(math.unit('-2 cm')).toString(), '4 cm^2');
|
||||
assert.equal(square(math.unit('0 cm')).toString(), '0 cm^2');
|
||||
});
|
||||
|
||||
it('should throw an error when used with a string', function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user