| 1 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 2 | Text _.autodoc.member.LogAditiveEffect = |
|---|
| 3 | "Builds a NameBlock that can be used as non linear filter by method " |
|---|
| 4 | "NonLinBlock in order to simulate alpha coefficents of additive effects X1 " |
|---|
| 5 | "in a logarithmic model as this one\n" |
|---|
| 6 | "\n" |
|---|
| 7 | " Log(Y-X1*alpha) = X2*beta + e; e ~ N(0,s^2) \n" |
|---|
| 8 | "\n" |
|---|
| 9 | "that can be written so\n" |
|---|
| 10 | "\n" |
|---|
| 11 | " Log(Y) = F + X2*beta + e; e ~ N(0,s^2) \n" |
|---|
| 12 | "\n" |
|---|
| 13 | "where the non linear filter of output is defined as\n" |
|---|
| 14 | "\n" |
|---|
| 15 | " F = Log(Y)-Log(Y-X1*alpha)\n" |
|---|
| 16 | "\n" |
|---|
| 17 | "Linear parameter omega will be simulated by BSR linear block.\n" |
|---|
| 18 | "Arguments are:\n" |
|---|
| 19 | " Real enabled : enables/disables non linear filter \n" |
|---|
| 20 | " Text segmentName : identifier of affected output segment \n" |
|---|
| 21 | " Anything origOutput : Series or vector output in original metric\n" |
|---|
| 22 | " Set aditiveInputs : Set of NameBlock defining X1 and alpha\n" |
|---|
| 23 | ""; |
|---|
| 24 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 25 | NameBlock LogAditiveEffect |
|---|
| 26 | ( |
|---|
| 27 | Real enabled, |
|---|
| 28 | Text segmentName, |
|---|
| 29 | Anything origOutput, |
|---|
| 30 | Date firstDate, |
|---|
| 31 | Date lastDate, |
|---|
| 32 | Set aditiveInputs |
|---|
| 33 | ) |
|---|
| 34 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 35 | {[[ |
|---|
| 36 | Real _.isNonLinearFilter = True; |
|---|
| 37 | |
|---|
| 38 | Real _.enabled = enabled; |
|---|
| 39 | Text _.cleanSegmentName = segmentName; |
|---|
| 40 | Anything _.origOutput = origOutput; |
|---|
| 41 | Date _.firstDate = firstDate; |
|---|
| 42 | Date _.lastDate = lastDate; |
|---|
| 43 | Set _.aditiveInputs = aditiveInputs; |
|---|
| 44 | |
|---|
| 45 | Text _.segmentName = segmentName+"::Noise"; |
|---|
| 46 | //Identifier of original input |
|---|
| 47 | Text _.inputName = "LogAditiveEffect"; |
|---|
| 48 | //Identifier prefix for non linear parameters |
|---|
| 49 | Text _.name = "NonLinearFilterBlk::"+_.cleanSegmentName+"::LogAdEff"; |
|---|
| 50 | Text _MID = "["+_.name+"]"; |
|---|
| 51 | |
|---|
| 52 | //Names of non linear parameters |
|---|
| 53 | Set _.colNames = EvalSet(_.aditiveInputs, Text(NameBlock inp) |
|---|
| 54 | { |
|---|
| 55 | _.name+"::"+Name(inp) |
|---|
| 56 | }); |
|---|
| 57 | |
|---|
| 58 | Real _.hasVectorData = Grammar(_.origOutput)=="Matrix"; |
|---|
| 59 | Matrix _.Y = If(_.hasVectorData, _.origOutput, |
|---|
| 60 | { |
|---|
| 61 | Tra(SerSetMat([[_.origOutput]],_.firstDate,_.lastDate)) |
|---|
| 62 | }); |
|---|
| 63 | Matrix _.LogY = Log(_.Y); |
|---|
| 64 | |
|---|
| 65 | Matrix _.X = If(_.hasVectorData, |
|---|
| 66 | { |
|---|
| 67 | Group("ConcatColumns", EvalSet(_.aditiveInputs, Matrix(NameBlock inp) |
|---|
| 68 | { |
|---|
| 69 | inp::_.vector |
|---|
| 70 | })) |
|---|
| 71 | }, |
|---|
| 72 | { |
|---|
| 73 | Set aux = EvalSet(_.aditiveInputs, Serie(NameBlock inp) |
|---|
| 74 | { |
|---|
| 75 | inp::_.serie |
|---|
| 76 | }); |
|---|
| 77 | Tra(SerSetMat(aux,_.firstDate,_.lastDate)) |
|---|
| 78 | }); |
|---|
| 79 | Real _.n = Columns(_.X); |
|---|
| 80 | |
|---|
| 81 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 82 | //In order to apply logarihtm it must be matched _.Y-_.X*alpha |
|---|
| 83 | Real checkAlpha(Matrix alpha) |
|---|
| 84 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 85 | { |
|---|
| 86 | Matrix aux.2 = _.Y -_.X*alpha; |
|---|
| 87 | Real aux.3 = MatMin(aux.2); |
|---|
| 88 | If(aux.3<=0, |
|---|
| 89 | { |
|---|
| 90 | WriteLn(_MID+"Values of 'alpha' don't match " |
|---|
| 91 | "Y-X*alpha > 0"+"\n"+ |
|---|
| 92 | "alpha="+Replace(""<<Matrix Tra(alpha),"\n"," "),"E"); |
|---|
| 93 | False |
|---|
| 94 | }, |
|---|
| 95 | { |
|---|
| 96 | //WriteLn("TRACE "+_MID+"Initial values 'alpha' of output filter match Y-X*alpha > 0"); |
|---|
| 97 | True |
|---|
| 98 | }) |
|---|
| 99 | }; |
|---|
| 100 | |
|---|
| 101 | Matrix _.alpha = SetCol(EvalSet(_.aditiveInputs, Real(NameBlock inp) |
|---|
| 102 | { |
|---|
| 103 | inp::_.initValue |
|---|
| 104 | })); |
|---|
| 105 | |
|---|
| 106 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 107 | //Called by BysMcmc::Bsr::Gibbs::NonLinBlock at initialization time |
|---|
| 108 | Real initialize(Real unused) |
|---|
| 109 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 110 | { |
|---|
| 111 | Real ok = checkAlpha(_.alpha); |
|---|
| 112 | If(ok, |
|---|
| 113 | WriteLn(_MID+"Initial values 'alpha' match Y-X*alpha > 0")); |
|---|
| 114 | ok |
|---|
| 115 | }; |
|---|
| 116 | |
|---|
| 117 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 118 | //Mandatory methods for all non linear filters |
|---|
| 119 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 120 | |
|---|
| 121 | //Identifies the filter |
|---|
| 122 | Text get.name(Real unused) { _.name }; |
|---|
| 123 | //Identifies the segment |
|---|
| 124 | Text get.segmentName(Real unused) { _.segmentName }; |
|---|
| 125 | //Parameters of non linear block |
|---|
| 126 | Set get.colNames(Real unused) { _.colNames }; |
|---|
| 127 | |
|---|
| 128 | VMatrix _Y = Mat2VMat(_.Y); |
|---|
| 129 | VMatrix _X = Mat2VMat(_.X); |
|---|
| 130 | |
|---|
| 131 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 132 | Set get.bounds(Real paramIdx, Matrix paramValues) |
|---|
| 133 | //Returns left and right bounds for paramIdx-th parameter for current |
|---|
| 134 | //values of the rest of them |
|---|
| 135 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 136 | { |
|---|
| 137 | //WriteLn("TRACE "+_MID+"::get.bounds("<<paramIdx+","+Replace(""<<Matrix Tra(paramValues),"\n"," ")+")"); |
|---|
| 138 | NameBlock userBounds = _.aditiveInputs[paramIdx]; |
|---|
| 139 | //WriteLn("TRACE "+_MID+"::get.bounds userBounds::_.minimum"<<userBounds::_.minimum); |
|---|
| 140 | //WriteLn("TRACE "+_MID+"::get.bounds userBounds::_.maximum"<<userBounds::_.maximum); |
|---|
| 141 | Set localBounds = GetBoundsInPolytope(_X, _Y, Mat2VMat(paramValues), paramIdx); |
|---|
| 142 | If(!Card(localBounds), |
|---|
| 143 | { |
|---|
| 144 | WriteLn(_MID+"Current values 'alpha' of output filter don't match " |
|---|
| 145 | "Y-X*alpha > 0"+"\n"+ |
|---|
| 146 | "alpha="+Replace(""<<Matrix Tra(paramValues),"\n"," "),"E"); |
|---|
| 147 | Real Stop |
|---|
| 148 | }, |
|---|
| 149 | { |
|---|
| 150 | //WriteLn("TRACE "+_MID+"::get.bounds localBounds = "<<localBounds); |
|---|
| 151 | //WriteLn("TRACE "+_MID+"::get.bounds localBounds::lower"<<localBounds::Lower); |
|---|
| 152 | //WriteLn("TRACE "+_MID+"::get.bounds localBounds::upper"<<localBounds::Upper); |
|---|
| 153 | Real lower = Max(userBounds::_.minimum, localBounds::Lower); |
|---|
| 154 | Real upper = Min(userBounds::_.maximum, localBounds::Upper); |
|---|
| 155 | //WriteLn("TRACE "+_MID+"::get.bounds lower"<<lower); |
|---|
| 156 | //WriteLn("TRACE "+_MID+"::get.bounds upper"<<upper); |
|---|
| 157 | [[lower, upper]] |
|---|
| 158 | }) |
|---|
| 159 | }; |
|---|
| 160 | |
|---|
| 161 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 162 | Real set.parameter(Matrix paramValues) |
|---|
| 163 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 164 | { |
|---|
| 165 | //WriteLn("TRACE "+_MID+"::set.parameter 1 ("<<Replace(""<<Matrix Tra(paramValues),"\n"," ")+")"); |
|---|
| 166 | If(!checkAlpha(paramValues),0, |
|---|
| 167 | { |
|---|
| 168 | Matrix _.alpha := paramValues; |
|---|
| 169 | 1 |
|---|
| 170 | }) |
|---|
| 171 | }; |
|---|
| 172 | |
|---|
| 173 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 174 | Matrix get.parameter(Real unused) |
|---|
| 175 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 176 | { |
|---|
| 177 | _.alpha |
|---|
| 178 | }; |
|---|
| 179 | |
|---|
| 180 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 181 | Matrix eval(Matrix paramValues) |
|---|
| 182 | //Returns the filter matrix |
|---|
| 183 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 184 | { |
|---|
| 185 | Real set.parameter(paramValues); |
|---|
| 186 | _.LogY - Log(_.Y - _.X * _.alpha) |
|---|
| 187 | }; |
|---|
| 188 | |
|---|
| 189 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 190 | Anything build.series(Real unused) |
|---|
| 191 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 192 | { |
|---|
| 193 | Matrix z = eval(get.parameter(0)); |
|---|
| 194 | If(_.hasVectorData, z, |
|---|
| 195 | MatSerSet(Tra(z), Dating(_.origOutput), _.firstDate)[1]) |
|---|
| 196 | }; |
|---|
| 197 | |
|---|
| 198 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 199 | Anything build.series.for.param(Matrix alpha) |
|---|
| 200 | /////////////////////////////////////////////////////////////////////////// |
|---|
| 201 | { |
|---|
| 202 | set.parameter(alpha); |
|---|
| 203 | build.series(0) |
|---|
| 204 | } |
|---|
| 205 | |
|---|
| 206 | ]]}; |
|---|
| 207 | |
|---|
| 208 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 209 | NameBlock LogAditiveEffect.Serie |
|---|
| 210 | ( |
|---|
| 211 | Real enabled, |
|---|
| 212 | Text segmentName, |
|---|
| 213 | Serie origOutput, |
|---|
| 214 | Date firstDate, |
|---|
| 215 | Date lastDate, |
|---|
| 216 | Set aditiveInputs |
|---|
| 217 | ) |
|---|
| 218 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 219 | { |
|---|
| 220 | LogAditiveEffect(enabled,segmentName,origOutput, |
|---|
| 221 | firstDate, lastDate, aditiveInputs) |
|---|
| 222 | }; |
|---|
| 223 | |
|---|
| 224 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 225 | NameBlock LogAditiveEffect.Vector |
|---|
| 226 | ( |
|---|
| 227 | Real enabled, |
|---|
| 228 | Text segmentName, |
|---|
| 229 | Matrix origOutput, |
|---|
| 230 | Set aditiveInputs |
|---|
| 231 | ) |
|---|
| 232 | ////////////////////////////////////////////////////////////////////////////// |
|---|
| 233 | { |
|---|
| 234 | LogAditiveEffect(enabled,segmentName,origOutput, |
|---|
| 235 | UnknownDate, UnknownDate, aditiveInputs) |
|---|
| 236 | }; |
|---|