| 1 | /* -*- mode: C++ -*- */ |
|---|
| 2 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 3 | // FILE : BaseC2.LinComb.tol |
|---|
| 4 | // PURPOSE: Defines class @BaseC2.LinComb |
|---|
| 5 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 6 | |
|---|
| 7 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 8 | Text _.autodoc.member.BaseC2.LinComb = "Defines a new base B2 of " |
|---|
| 9 | "order K2 as a linear combination B2=B1*V of functions of a previous base " |
|---|
| 10 | "B1 of order K1>=K2. The matrix of change V must have rank K2 to ensure " |
|---|
| 11 | "linear independence."; |
|---|
| 12 | Class @BaseC2.LinComb : @BaseC2.Cache |
|---|
| 13 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 14 | { |
|---|
| 15 | @BaseC2 _.base; |
|---|
| 16 | VMatrix _.V; |
|---|
| 17 | VMatrix _.Vi; |
|---|
| 18 | |
|---|
| 19 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 20 | Static Text _.autodoc.member.New = "Creates an instance B2 of " |
|---|
| 21 | "@BaseC2.LinComb as B2 = B1*V"; |
|---|
| 22 | Static @BaseC2.LinComb New(@BaseC2 B1, VMatrix V, VMatrix Vi) |
|---|
| 23 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 24 | { |
|---|
| 25 | Real n = B1::_.n; |
|---|
| 26 | |
|---|
| 27 | @BaseC2.LinComb aux = [[ |
|---|
| 28 | Real _.n = B1::_.n; |
|---|
| 29 | Real _.K = VColumns(V); |
|---|
| 30 | @BaseC2 _.base = base; |
|---|
| 31 | VMatrix _.V = V; |
|---|
| 32 | VMatrix _.Vi = Vi |
|---|
| 33 | ]]}; |
|---|
| 34 | |
|---|
| 35 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 36 | Static Text _.autodoc.member.Compact.Ratio = "Creates an instance of " |
|---|
| 37 | "@BaseC2.LinComb that is close to be orthonormal and has at least " |
|---|
| 38 | "the specified ratio of information of original base"; |
|---|
| 39 | Static @BaseC2.LinComb Compact.Ratio( |
|---|
| 40 | @BaseC2 base, |
|---|
| 41 | Real informationRatio) |
|---|
| 42 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 43 | { |
|---|
| 44 | Real K1 = base::_.K; |
|---|
| 45 | |
|---|
| 46 | VMatrix u = Rand(K1*10, K1, -1, 1); |
|---|
| 47 | |
|---|
| 48 | VMatrix Pu = Group("ConcatColumns", For(1, K1, VMatrix(Real k) |
|---|
| 49 | { |
|---|
| 50 | base::function.v(k,u) |
|---|
| 51 | })); |
|---|
| 52 | |
|---|
| 53 | Set Pu.svd = SVD(VMat2Mat(Pu)); |
|---|
| 54 | |
|---|
| 55 | Matrix Pu.eigenvalue = Tra(SubDiag(Pu.svd[2],0)); |
|---|
| 56 | Matrix Pu.eigenvalueCum = |
|---|
| 57 | { |
|---|
| 58 | Matrix aux = DifEq(1/(1-B),Pu.eigenvalue); |
|---|
| 59 | aux*(1/MatSum(Pu.eigenvalue)) |
|---|
| 60 | }; |
|---|
| 61 | Matrix ratio = Rand(K1,1,informationRatio,informationRatio); |
|---|
| 62 | Real K = MatSum(LE(Pu.eigenvalueCum,ratio)); |
|---|
| 63 | Set range.K = Range(1,K,1); |
|---|
| 64 | VMatrix V = Mat2VMat(SubCol(Pu.svd[3],range.K)); |
|---|
| 65 | VMatrix D = Eye(K,K,0,RPow(Mat2VMat(SubRow(Pu.eigenvalue,range.K)),+1)); |
|---|
| 66 | VMatrix Di = Eye(K,K,0,RPow(Mat2VMat(SubRow(Pu.eigenvalue,range.K)),-1)); |
|---|
| 67 | VMatrix W = V*Di; |
|---|
| 68 | VMatrix Wi = D*Tra(V); |
|---|
| 69 | New(base, W, Wi) |
|---|
| 70 | }; |
|---|
| 71 | |
|---|
| 72 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 73 | Static Text _.autodoc.member.Compact.K = "Creates an instance of " |
|---|
| 74 | "@BaseC2.LinComb that is close to be orthonormal and has exactly K " |
|---|
| 75 | "elements"; |
|---|
| 76 | Static @BaseC2.LinComb Compact.K( |
|---|
| 77 | @BaseC2 base, |
|---|
| 78 | Real K) |
|---|
| 79 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 80 | { |
|---|
| 81 | Set range.K = Range(1,K,1); |
|---|
| 82 | Real K1 = base::_.K; |
|---|
| 83 | |
|---|
| 84 | VMatrix u = Rand(K1*10, K1, -1, 1); |
|---|
| 85 | |
|---|
| 86 | VMatrix Pu = Group("ConcatColumns", For(1, K1, VMatrix(Real k) |
|---|
| 87 | { |
|---|
| 88 | base::function.v(k,u) |
|---|
| 89 | })); |
|---|
| 90 | |
|---|
| 91 | Set Pu.svd = SVD(VMat2Mat(Pu)); |
|---|
| 92 | |
|---|
| 93 | Matrix Pu.eigenvalue = Tra(SubDiag(Pu.svd[2],0)); |
|---|
| 94 | VMatrix V = Mat2VMat(SubCol(Pu.svd[3],range.K)); |
|---|
| 95 | VMatrix D = Eye(K,K,0,RPow(Mat2VMat(SubRow(Pu.eigenvalue,range.K)),+1)); |
|---|
| 96 | VMatrix Di = Eye(K,K,0,RPow(Mat2VMat(SubRow(Pu.eigenvalue,range.K)),-1)); |
|---|
| 97 | VMatrix W = V*Di; |
|---|
| 98 | VMatrix Wi = D*Tra(V); |
|---|
| 99 | New(base, W, Wi) |
|---|
| 100 | }; |
|---|
| 101 | |
|---|
| 102 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 103 | Real _build.cache(VMatrix X, Real order) |
|---|
| 104 | //////////////////////////////////////////////////////////////////////////// |
|---|
| 105 | { |
|---|
| 106 | Real _.base::upgrade.cache(X,order); |
|---|
| 107 | VMatrix If(order>=0, { _.function := |
|---|
| 108 | _.base::function.m(X)*_.V |
|---|
| 109 | }); |
|---|
| 110 | Set If(order>=1, { _.partial.derivative.1 := |
|---|
| 111 | For(1, _.n, VMatrix(Real i) |
|---|
| 112 | { |
|---|
| 113 | _.base::partial.derivative.1.m(X,i)*_.V |
|---|
| 114 | }) |
|---|
| 115 | }); |
|---|
| 116 | Set If(order>=2, { _.partial.derivative.2 := |
|---|
| 117 | For(1, _.n, Set(Real i) |
|---|
| 118 | { |
|---|
| 119 | For(1, i, VMatrix(Real j) |
|---|
| 120 | { |
|---|
| 121 | _.base::partial.derivative.2.m(X,i,j)*_.V |
|---|
| 122 | }) |
|---|
| 123 | }) |
|---|
| 124 | }); |
|---|
| 125 | True |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | }; |
|---|