It's necessary to get
from
list = {{a1, b1, c1}, {a2, b2, c2}, {a3, b3, c3},{a4, b4, c4}, {a5, b5, c5}};
I'd like to do this with ReplaceList
. Is it feasible? Or, maybe, you know a better way?
Written for brevity:
list = {{a1, b1, c1}, {a2, b2, c2}, {a3, b3, c3}, {a4, b4, c4}, {a5, b5, c5}};
f[x_][n_] := {Tr@#, Sqrt@Tr[#2^2], x[[3, n + 1]] Tr@# / #.#3} & @@ x[[All, ;; n]]
f[list\[Transpose]] ~Array~ 4
{{a1, Sqrt[b1^2], c2/c1}, {a1 + a2, Sqrt[b1^2 + b2^2], ((a1 + a2) c3)/( a1 c1 + a2 c2)}, {a1 + a2 + a3, Sqrt[b1^2 + b2^2 + b3^2], ((a1 + a2 + a3) c4)/( a1 c1 + a2 c2 + a3 c3)}, {a1 + a2 + a3 + a4, Sqrt[b1^2 + b2^2 + b3^2 + b4^2], ((a1 + a2 + a3 + a4) c5)/(a1 c1 + a2 c2 + a3 c3 + a4 c4)}}
Sqrt[b1^2]
remains in the output rather than b1
but I think this is reasonable.
As ciao comments code facilitates answers rather than pictures. As the base list is small I post the following. There will almost certainly be better ways and I have not simplified Sqrt
:
dat = {{a1, b1, c1}, {a2, b2, c2}, {a3, b3, c3}, {a4, b4, c4}, {a5, b5, c5}}
func[u_] := FoldList[Append, {u[[1]]}, u[[2 ;; -2]]]
col1 = Accumulate[Most@dat[[All, 1]]];
col2 = Sqrt[#.#] & /@ func[dat[[All, 2]]];
col3 =
MapThread[
#1/#2 &,
{Rest@dat[[All, 3]],
MapThread[
#1.#2/Plus @@ #2 &,
{func[dat[[All, 3]]], func[dat[[All, 1]]]}]}
];
Transpose[{col1, col2, col3}]
this yields:
(*{{a1, Sqrt[b1^2], c2/c1}, {a1 + a2, Sqrt[
b1^2 + b2^2], ((a1 + a2) c3)/(a1 c1 + a2 c2)}, {a1 + a2 + a3, Sqrt[
b1^2 + b2^2 + b3^2], ((a1 + a2 + a3) c4)/(
a1 c1 + a2 c2 + a3 c3)}, {a1 + a2 + a3 + a4, Sqrt[
b1^2 + b2^2 + b3^2 + b4^2], ((a1 + a2 + a3 + a4) c5)/(
a1 c1 + a2 c2 + a3 c3 + a4 c4)}}*)
Not very efficient, but this brute force approach has the advantage of being very easy to code.
data = {{a1, b1, c1}, {a2, b2, c2}, {a3, b3, c3}, {a4, b4, c4}, {a5, b5, c5}};
{aa, bb, cc} = Transpose @ data;
as = Most @ Accumulate[aa];
bs = Most @ Sqrt @ Accumulate[bb^2];
cs =
Table[
Module[{as = aa[[;; i]], cs = cc[[;; i]]}, cc[[i + 1]] Total[as]/(as.cs)],
{i, Length @ cc - 1}]
result = Transpose @ {as, bs, cs}
{{a1, Sqrt[b1^2], c2/c1}, {a1 + a2, Sqrt[b1^2 + b2^2], ((a1 + a2)*c3)/(a1*c1 + a2*c2)}, {a1 + a2 + a3, Sqrt[b1^2 + b2^2 + b3^2], ((a1 + a2 + a3)*c4)/(a1*c1 + a2*c2 + a3*c3)}, {a1 + a2 + a3 + a4, Sqrt[b1^2 + b2^2 + b3^2 + b4^2], ((a1 + a2 + a3 + a4)*c5)/(a1*c1 + a2*c2 + a3*c3 + a4*c4)}}
Sqrt[b1 + b2 + b3]
should be Sqrt[b1^2 + b2^2 + b3^2]
etc.
$\endgroup$
Commented
Jul 17, 2015 at 13:29
l[n_, x_] := Transpose[list[[;; n]]][[x]]
{Tr@l[#, 1], Norm@l[#, 2], Last@l[# + 1, -1]/l[#, 1].l[#, 3] Tr@l[#, 1]} & /@ Range@4
Sqrt[b1^2]
:)
$\endgroup$
Commented
Jul 17, 2015 at 13:35
My take (but the fractions in the third element are always converted from a/(b/c)
to ac/b
, such is life).
transform =
{Total@#1[[1 ;; -2, 1]],
Sqrt[Total@(#1[[1 ;; -2, 2]]^2)],
#1[[-1, 3]]/((#1[[1 ;; -2, 1]]).(#1[[1 ;; -2, 3]])/Total@#1[[1 ;; -2, 1]])
} &
transform[list[[1;;#]]]&/@Range[2,Length@list]
Alternatively, because First
, Rest
, Most
, and Last
are better than Part
:
transform =
{Total@(First /@ Most@#),
Sqrt[Total@(Most@#^2)][[2]],
Last@Last@#/((First /@ Most@#).(Last /@ Most@#)/Total@(First /@ Most@#))
} &
And here's a different enough approach to merit a separate answer.
ListCorrelate[
{1, 1},
Accumulate@list,
{1, -1}, {}, #2 &
{#[[1]], Sqrt@Total@({Sequence @@ #1[[2]]}^2),
#2[[-1, -1]] #[[1]]/{Sequence @@ #[[1]]}.{Sequence @@ Last@#}} &, 1]
Before programming, you should analyse the construction of the formula.
For the first column, you could construct the following list
{{a1},
{a1, a2},
{a1, a2, a3},
{a1, a2, a3, a4}}
For the second column
{{b1},
{b1, b2},
{b1, b2, b3},
{b1, b2, b3, b4}}
For the last column, constructing the list as follow
{{{a1}, {c1}},
{{a1, a2}, {c1, c2}},
{{a1, a2, a3}, {c1, c2, c3}},
{{a1, a2, a3, a4}, {c1, c2, c3, c4}}}
{c2, c3, c4, c5}
Implementation
data = {{a1, b1, c1}, {a2, b2, c2}, {a3, b3, c3}, {a4, b4, c4}, {a5, b5, c5}}
{lstA, lstB, lstC} = Transpose@data;
len = Length@data;
Then
col1 = Plus @@@ (lstA[[1 ;; #]] & /@ Range[len - 1])
(*col1 = Accumulate[Most@lstA]*)
col2 = Sqrt[#.#] & /@ (lstB[[1 ;; #]] & /@ Range[len - 1])
col3 =
(Plus @@ #1/#1.#2 &) @@@ ({lstA[[1 ;; #]], lstC[[1 ;; #]]} & /@
Range[len - 1]) lstC[[2 ;;]]
Lastly, you can transpose the three columns.
Transpose[{col1, col2, col3}]
ReplacePart
. $\endgroup${a1, b1, c2/a1}
? $\endgroup${a1,b1,c2/c1}
$\endgroup$