View Raw SPL
/*****************************************************************************
* *
* NORM.SPL Copyright (C) 2001, 2014 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Returns the norm of a series or array *
* *
* Revisions: 24 Jul 2001 RRR Creation *
* 6 Jun 2014 RRR -2, -1 modes *
* *
*****************************************************************************/
#include
#if @HELP_NORM
NORM
Purpose: Calculates the norm of a series or array
Syntax: NORM(m, mode)
m - input series or array, defaults to the current series
mode - optional parameter, type of norm calculation,
-2: smallest singular value
-1: 1-norm, min of the column sum
1: 1-norm, max of the column sum
2: largest singular value
inf: max of the row sum
-inf: min of the row sum
"fro": Froenius norm
defaults to 2, largest singular value
Returns: A real, the norm value
Example:
a = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
norm(a) == 16.848103
norm(a, -2) == 4.418425e-16
norm(a, -1) == 12
norm(a, 1) == 18
norm(a, 2) == 16.848103
norm(a, inf) == 24
norm(a, -inf) == 6
norm(a, "fro") == 16.881943
Remarks:
The mode parameter specifies the following rank calculations:
Mode Series Array
_____________________________________________________
-1 sum(mag(m)^(-1)) min(colsum(mag(m)))
1 sum(mag(m)) max(colsum(mag(m)))
-2 sum(mag(m)^(-2)/2 min(svd(m))
2 max(svd(m)) max(svd(m))
N sum(mag(m)^N)/(1/N) undefined
inf max(mag(m)) max(colsum(mag(m)')')
-inf min(mag(m)) min(colsum(mag(m)')')
"fro" undefined sqrt(sum(diag(m'*^m)))
See Also:
Rank
Svd
#endif
/* series or array norm */
norm(m, mode)
{
local nc, nr, n;
if (argc < 2)
{
/* default mode and possible series */
if (argc < 1)
{
mode = 2;
m = refseries(1);
}
else if (not(isarray(m)))
{
m = {m};
mode = 1;
}
else
{
mode = 2;
}
}
if (not(isarray(m))) m = {m};
(nr, nc) = size(m);
/* check if empty */
if (nr == 0) return(0);
if (nr == 1)
{
/* turn into vector */
m = transpose(m);
(nr, nc) = size(m);
}
if (nc > 1)
{
/* array */
if (mode == inf)
{
n = max(rowreduce(mag(m), "+"));
}
else if (mode == -inf)
{
n = min(rowreduce(mag(m), "+"));
}
else
{
switch (mode)
{
case -1:
n = min(colsum(mag(m)));
break;
case 1:
n = max(colsum(mag(m)));
break;
case -2:
n = min(svd(m));
break;
case 2:
n = max(svd(m));
break;
case "fro":
n = mag(sqrt(sum(diag(m~^ *^ m))));
break;
default:
error('norm - use +-1, +-2, +-inf or "fro" for arrays');
break;
}
}
}
else
{
/* series */
if (mode == inf)
{
n = max(mag(m));
}
else if (mode == -inf)
{
n = min(mag(m));
}
else
{
switch (mode)
{
case 2:
/* use singular values */
n = getpt(svd(m), 1);
break;
default:
if (isscalar(mode))
{
n = sum(mag(m) ^ mode) ^ (1 / mode);
}
else
{
error("norm - unknown mode for series");
}
}
}
}
return(n);
}