mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
math.norm()
This commit is contained in:
parent
b1c0428e8c
commit
fc8dde607d
@ -3,12 +3,9 @@
|
||||
module.exports = function (math) {
|
||||
var util = require('../../util/index'),
|
||||
|
||||
array = require('../../../lib/util/array'),
|
||||
|
||||
BigNumber = math.type.BigNumber,
|
||||
Complex = require('../../type/Complex'),
|
||||
Matrix = math.type.Matrix,
|
||||
collection = math.collection,
|
||||
|
||||
isNumber = util.number.isNumber,
|
||||
isBoolean = util['boolean'].isBoolean,
|
||||
@ -68,11 +65,11 @@ module.exports = function (math) {
|
||||
var re = Math.abs(x.re);
|
||||
var im = Math.abs(x.im);
|
||||
if (re >= im) {
|
||||
var x = im / re;
|
||||
return re * Math.sqrt(1 + x * x);
|
||||
var i = im / re;
|
||||
return re * Math.sqrt(1 + i * i);
|
||||
}
|
||||
var y = re / im;
|
||||
return im * Math.sqrt(1 + y * y);
|
||||
var j = re / im;
|
||||
return im * Math.sqrt(1 + j * j);
|
||||
}
|
||||
|
||||
if (x instanceof BigNumber) {
|
||||
@ -86,8 +83,13 @@ module.exports = function (math) {
|
||||
}
|
||||
|
||||
if (isArray(x)) {
|
||||
// use matrix optimized operations
|
||||
return norm(math.matrix(x), p);
|
||||
}
|
||||
|
||||
if (x instanceof Matrix) {
|
||||
// size
|
||||
var sizeX = array.size(x);
|
||||
var sizeX = x.size();
|
||||
// missing p
|
||||
if (p == null)
|
||||
p = 2;
|
||||
@ -97,21 +99,25 @@ module.exports = function (math) {
|
||||
if (p === Number.POSITIVE_INFINITY || p === 'inf') {
|
||||
// norm(x, Infinity) = max(abs(x))
|
||||
var n;
|
||||
math.forEach(x, function (value) {
|
||||
var v = math.abs(value);
|
||||
if (!n || math.larger(v, n))
|
||||
n = v;
|
||||
});
|
||||
x.forEach(
|
||||
function (value) {
|
||||
var v = math.abs(value);
|
||||
if (!n || math.larger(v, n))
|
||||
n = v;
|
||||
},
|
||||
true);
|
||||
return n;
|
||||
}
|
||||
if (p === Number.NEGATIVE_INFINITY || p === '-inf') {
|
||||
// norm(x, -Infinity) = min(abs(x))
|
||||
var n;
|
||||
math.forEach(x, function (value) {
|
||||
var v = math.abs(value);
|
||||
if (!n || math.smaller(v, n))
|
||||
n = v;
|
||||
});
|
||||
x.forEach(
|
||||
function (value) {
|
||||
var v = math.abs(value);
|
||||
if (!n || math.smaller(v, n))
|
||||
n = v;
|
||||
},
|
||||
true);
|
||||
return n;
|
||||
}
|
||||
if (p === 'fro')
|
||||
@ -121,9 +127,11 @@ module.exports = function (math) {
|
||||
if (!math.equal(p, 0)) {
|
||||
// norm(x, p) = sum(abs(xi) ^ p) ^ 1/p
|
||||
var n = 0;
|
||||
math.forEach(x, function (value) {
|
||||
n = math.add(math.pow(math.abs(value), p), n);
|
||||
});
|
||||
x.forEach(
|
||||
function (value) {
|
||||
n = math.add(math.pow(math.abs(value), p), n);
|
||||
},
|
||||
true);
|
||||
return math.pow(n, 1 / p);
|
||||
}
|
||||
return Number.POSITIVE_INFINITY;
|
||||
@ -136,39 +144,34 @@ module.exports = function (math) {
|
||||
if (p == 1) {
|
||||
// norm(x) = the largest column sum
|
||||
var c = [];
|
||||
// loop rows
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
var r = x[i];
|
||||
// loop columns
|
||||
for (var j = 0; j < r.length; j++) {
|
||||
c[j] = math.add(c[j] || 0, math.abs(r[j]));
|
||||
}
|
||||
}
|
||||
x.forEach(
|
||||
function (value, index) {
|
||||
var j = index[1];
|
||||
c[j] = math.add(c[j] || 0, math.abs(value));
|
||||
},
|
||||
true);
|
||||
return math.max(c);
|
||||
}
|
||||
if (p == Number.POSITIVE_INFINITY || p === 'inf') {
|
||||
// norm(x) = the largest row sum
|
||||
var n = 0;
|
||||
// loop rows
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
var rs = 0;
|
||||
var r = x[i];
|
||||
// loop columns
|
||||
for (var j = 0; j < r.length; j++) {
|
||||
rs = math.add(rs, math.abs(r[j]));
|
||||
}
|
||||
if (math.larger(rs, n))
|
||||
n = rs;
|
||||
}
|
||||
return n;
|
||||
var r = [];
|
||||
x.forEach(
|
||||
function (value, index) {
|
||||
var i = index[0];
|
||||
r[i] = math.add(r[i] || 0, math.abs(value));
|
||||
},
|
||||
true);
|
||||
return math.max(r);
|
||||
}
|
||||
if (p === 'fro') {
|
||||
// norm(x) = sqrt(sum(diag(x'x)))
|
||||
var d = math.diag(math.multiply(math.transpose(x), x));
|
||||
var d = x.transpose().multiply(x).diagonal();
|
||||
var s = 0;
|
||||
math.forEach(d, function (value) {
|
||||
s = math.add(value, s);
|
||||
});
|
||||
d.forEach(
|
||||
function (value) {
|
||||
s = math.add(s, value);
|
||||
},
|
||||
true);
|
||||
return math.sqrt(s);
|
||||
}
|
||||
if (p == 2) {
|
||||
@ -180,10 +183,6 @@ module.exports = function (math) {
|
||||
}
|
||||
}
|
||||
|
||||
if (x instanceof Matrix) {
|
||||
return norm(x.valueOf(), p);
|
||||
}
|
||||
|
||||
throw new math.error.UnsupportedTypeError('norm', x);
|
||||
};
|
||||
};
|
||||
|
||||
@ -664,8 +664,9 @@ module.exports = function (math) {
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
|
||||
*/
|
||||
CcsMatrix.prototype.forEach = function (callback) {
|
||||
CcsMatrix.prototype.forEach = function (callback, skipZeros) {
|
||||
// matrix instance
|
||||
var me = this;
|
||||
// rows and columns
|
||||
@ -682,17 +683,23 @@ module.exports = function (math) {
|
||||
for (var k = k0; k < k1; k++) {
|
||||
// row index
|
||||
var i = this._index[k];
|
||||
// zero values
|
||||
for (var x = p; x < i; x++)
|
||||
callback(0, [x, j], me);
|
||||
// check we need to process zeros
|
||||
if (!skipZeros) {
|
||||
// zero values
|
||||
for (var x = p; x < i; x++)
|
||||
callback(0, [x, j], me);
|
||||
}
|
||||
// value @ k
|
||||
callback(this._values[k], [i, j], me);
|
||||
// update pointer
|
||||
p = i + 1;
|
||||
}
|
||||
// zero values
|
||||
for (var y = p; y < rows; y++)
|
||||
callback(0, [y, j], me);
|
||||
// check we need to process zeros
|
||||
if (!skipZeros) {
|
||||
// zero values
|
||||
for (var y = p; y < rows; y++)
|
||||
callback(0, [y, j], me);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -656,8 +656,9 @@ module.exports = function (math) {
|
||||
* @param {function} callback The callback function is invoked with three
|
||||
* parameters: the value of the element, the index
|
||||
* of the element, and the Matrix being traversed.
|
||||
* @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
|
||||
*/
|
||||
CrsMatrix.prototype.forEach = function (callback) {
|
||||
CrsMatrix.prototype.forEach = function (callback, skipZeros) {
|
||||
// matrix instance
|
||||
var me = this;
|
||||
// rows and columns
|
||||
@ -674,17 +675,23 @@ module.exports = function (math) {
|
||||
for (var k = k0; k < k1; k++) {
|
||||
// column index
|
||||
var j = this._index[k];
|
||||
// zero values
|
||||
for (var x = p; x < j; x++)
|
||||
callback(0, [i, x], me);
|
||||
// check we need to process zeros
|
||||
if (!skipZeros) {
|
||||
// zero values
|
||||
for (var x = p; x < j; x++)
|
||||
callback(0, [i, x], me);
|
||||
}
|
||||
// value @ k
|
||||
callback(this._values[k], [i, j], me);
|
||||
// update pointer
|
||||
p = j + 1;
|
||||
}
|
||||
// zero values
|
||||
for (var y = p; y < columns; y++)
|
||||
callback(0, [i, y], me);
|
||||
// check we need to process zeros
|
||||
if (!skipZeros) {
|
||||
// zero values
|
||||
for (var y = p; y < columns; y++)
|
||||
callback(0, [i, y], me);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1114,6 +1114,19 @@ describe('CcsMatrix', function() {
|
||||
m.forEach(function (value) { output.push(value); });
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
|
||||
it('should process non-zero values', function() {
|
||||
var m = new CcsMatrix(
|
||||
[
|
||||
[1, 0],
|
||||
[0, 0]
|
||||
]
|
||||
);
|
||||
var counter = 0;
|
||||
|
||||
m.forEach(function () { counter++; }, true);
|
||||
assert(counter === 1);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new CcsMatrix([[1,2,3], [4,5,6]]);
|
||||
|
||||
@ -1095,6 +1095,19 @@ describe('CrsMatrix', function() {
|
||||
assert.deepEqual(output, []);
|
||||
});
|
||||
|
||||
it('should process non-zero values', function() {
|
||||
var m = new CrsMatrix(
|
||||
[
|
||||
[1, 0],
|
||||
[0, 0]
|
||||
]
|
||||
);
|
||||
var counter = 0;
|
||||
|
||||
m.forEach(function () { counter++; }, true);
|
||||
assert(counter === 1);
|
||||
});
|
||||
|
||||
it('should invoke callback with parameters value, index, obj', function() {
|
||||
var m = new CrsMatrix([[1,2,3], [4,5,6]]);
|
||||
var output = [];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user