In AWK
For 3 individual vectors of the form:
-2.772 -9.341 -2.857
-5.140 -6.597 -1.823
-2.730 -5.615 1.159
I would like to write a script that parses line by line to (i) normalise, (ii) divide by the norm for *each* vector.
I.e.
sqrt(-2.772^2 + -9.341^2 + -2.857^2)=10.154
-2.772/10.154 = -0.273, -9.341/10.154 = -0.919, -2.857/10.154 = -0.281
CarloM
April 4, 2012, 6:49am
2
[/tmp] awk '{nm=sqrt(($1*$1)+($2*$2)+($3*$3)); print $1/nm FS $2/nm FS $3/nm}' file
-0.273 -0.919946 -0.281371
-0.600509 -0.770732 -0.212982
-0.429911 -0.884231 0.182515
Why does the BEGIN/END commands in this script change the function of the script to loop over all records before doing the division by the norm?
awk 'BEGIN{s=0}{s = s + $1^2 + $2^2 + $3^2}END{print sqrt(s)}' file`
chrisjorg:
Why does the BEGIN/END commands in this script change the function of the script to loop over all records before doing the division by the norm?
awk 'BEGIN{s=0}{s = s + $1^2 + $2^2 + $3^2}END{print sqrt(s)}' file`
Statements in BEGIN block will be executed before reading any line of file and statements in END block will be executed after all the lines in file are read.
So, initially 's' is set to 0. And $1^2 + $2^2 + $3^2 of each line is added to 's' iteratively. After all the lines are read, sqrt(s) is printed.
General case:
awk '{normp=0;for(i=1;i<=NF;i++)normp+=$i*$i; for(i=1;i<=NF;i++)printf "%8.3f",$i/sqrt(normp);print ""}' infile