Changeset 16652


Ignore:
Timestamp:
03/06/19 13:14:23 (3 months ago)
Author:
gkronber
Message:

#2925: allow arbitrary number of arguments to +,-,*,/ operators, fixed bug in single-argument division

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs

    r16616 r16652  
    11611161        return nodeValues.NodeValue(node);
    11621162      } else if (node.Symbol is Addition) {
    1163         Assert(node.SubtreeCount == 2);
    11641163        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    1165         var g = InterpretRec(node.GetSubtree(1), nodeValues);
    1166         return f + g;
     1164        for (int i = 1; i < node.SubtreeCount; i++) {
     1165          f += InterpretRec(node.GetSubtree(i), nodeValues);
     1166        }
     1167        return f;
    11671168      } else if (node.Symbol is Multiplication) {
    1168         Assert(node.SubtreeCount == 2);
    11691169        var f = InterpretRec(node.GetSubtree(0), nodeValues);
    1170         var g = InterpretRec(node.GetSubtree(1), nodeValues);
    1171         return f * g;
     1170        for (int i = 1; i < node.SubtreeCount; i++) {
     1171          f *= InterpretRec(node.GetSubtree(i), nodeValues);
     1172        }
     1173        return f;
    11721174      } else if (node.Symbol is Subtraction) {
    1173         Assert(node.SubtreeCount <= 2);
    11741175        if (node.SubtreeCount == 1) {
    1175           var f = InterpretRec(node.GetSubtree(0), nodeValues);
    1176           return -f;
     1176          return -InterpretRec(node.GetSubtree(0), nodeValues);
    11771177        } else {
    11781178          var f = InterpretRec(node.GetSubtree(0), nodeValues);
    1179           var g = InterpretRec(node.GetSubtree(1), nodeValues);
    1180 
    1181           return f - g;
     1179          for (int i = 1; i < node.SubtreeCount; i++) {
     1180            f -= InterpretRec(node.GetSubtree(i), nodeValues);
     1181          }
     1182          return f;
    11821183        }
    11831184      } else if (node.Symbol is Division) {
    1184         Assert(node.SubtreeCount <= 2);
    1185 
    11861185        if (node.SubtreeCount == 1) {
    11871186          var f = InterpretRec(node.GetSubtree(0), nodeValues);
     
    11941193        } else {
    11951194          var f = InterpretRec(node.GetSubtree(0), nodeValues);
    1196           var g = InterpretRec(node.GetSubtree(1), nodeValues);
    1197 
    1198           // protected division
    1199           if (g.IsAlmost(0.0)) {
    1200             return 0;
    1201           } else {
    1202             return f / g;
    1203           }
     1195          for (int i = 1; i < node.SubtreeCount; i++) {
     1196            var g = InterpretRec(node.GetSubtree(i), nodeValues);
     1197            // protected division
     1198            if (g.IsAlmost(0.0)) {
     1199              return 0;
     1200            } else {
     1201              f /= g;
     1202            }
     1203          }
     1204          return f;
    12041205        }
    12051206      } else if (node.Symbol is Sine) {
     
    12491250        dz = Vector.CreateNew(nodeValues.NodeGradient(node)); // original gradient vectors are never changed by evaluation
    12501251      } else if (node.Symbol is Addition) {
    1251 
    1252         Assert(node.SubtreeCount == 2);
    12531252        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    1254         InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
    1255         z = f + g;
    1256         dz = df.Add(dg);
     1253        for (int i = 1; i < node.SubtreeCount; i++) {
     1254          InterpretRec(node.GetSubtree(i), nodeValues, out g, out dg);
     1255          f = f + g;
     1256          df = df.Add(dg);
     1257        }
     1258        z = f;
     1259        dz = df;
    12571260      } else if (node.Symbol is Multiplication) {
    1258 
    1259         Assert(node.SubtreeCount == 2);
    12601261        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    1261         InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
    1262         z = f * g;
    1263         dz = df.Scale(g).Add(dg.Scale(f));  // f'*g + f*g'
    1264 
     1262        for (int i = 1; i < node.SubtreeCount; i++) {
     1263          InterpretRec(node.GetSubtree(i), nodeValues, out g, out dg);
     1264          f = f * g;
     1265          df = df.Scale(g).Add(dg.Scale(f));  // f'*g + f*g'
     1266        }
     1267        z = f;
     1268        dz = df;
    12651269      } else if (node.Symbol is Subtraction) {
    1266 
    1267         Assert(node.SubtreeCount <= 2);
    12681270        if (node.SubtreeCount == 1) {
    12691271          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    12721274        } else {
    12731275          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    1274           InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
    1275           z = f - g;
    1276           dz = df.Subtract(dg);
    1277         }
    1278 
     1276          for (int i = 1; i < node.SubtreeCount; i++) {
     1277            InterpretRec(node.GetSubtree(i), nodeValues, out g, out dg);
     1278            f = f - g;
     1279            df = df.Subtract(dg);
     1280          }
     1281          z = f;
     1282          dz = df;
     1283        }
    12791284      } else if (node.Symbol is Division) {
    1280 
    1281         Assert(node.SubtreeCount <= 2);
    12821285        if (node.SubtreeCount == 1) {
    12831286          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    12881291          } else {
    12891292            z = 1.0 / f;
    1290             dz = df.Scale(z * z);
     1293            dz = df.Scale(-1 * z * z);
    12911294          }
    12921295        } else {
    12931296          InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    1294           InterpretRec(node.GetSubtree(1), nodeValues, out g, out dg);
    1295 
    1296           // protected division
    1297           if (g.IsAlmost(0.0)) {
    1298             z = 0;
    1299             dz = Vector.Zero;
    1300           } else {
    1301             var inv_g = 1.0 / g;
    1302             z = f * inv_g;
    1303 
    1304             dz = dg.Scale(-f * inv_g * inv_g).Add(df.Scale(inv_g));
    1305           }
    1306         }
    1307 
     1297          for (int i = 1; i < node.SubtreeCount; i++) {
     1298            InterpretRec(node.GetSubtree(i), nodeValues, out g, out dg);
     1299            // protected division
     1300            if (g.IsAlmost(0.0)) {
     1301              z = 0;
     1302              dz = Vector.Zero;
     1303              return;
     1304            } else {
     1305              var inv_g = 1.0 / g;
     1306              f = f * inv_g;
     1307              df = dg.Scale(-f * inv_g * inv_g).Add(df.Scale(inv_g));
     1308            }
     1309          }
     1310          z = f;
     1311          dz = df;
     1312        }
    13081313      } else if (node.Symbol is Sine) {
    1309 
    13101314        Assert(node.SubtreeCount == 1);
    13111315        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
    13121316        z = Math.Sin(f);
    13131317        dz = df.Scale(Math.Cos(f));
    1314 
    13151318      } else if (node.Symbol is Cosine) {
    1316 
    13171319        Assert(node.SubtreeCount == 1);
    13181320        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    13201322        dz = df.Scale(-Math.Sin(f));
    13211323      } else if (node.Symbol is Square) {
    1322 
    13231324        Assert(node.SubtreeCount == 1);
    13241325        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    13261327        dz = df.Scale(2.0 * f);
    13271328      } else if (node.Symbol is Exponential) {
    1328 
    13291329        Assert(node.SubtreeCount == 1);
    13301330        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
     
    13321332        dz = df.Scale(Math.Exp(f));
    13331333      } else if (node.Symbol is Logarithm) {
    1334 
    13351334        Assert(node.SubtreeCount == 1);
    13361335        InterpretRec(node.GetSubtree(0), nodeValues, out f, out df);
Note: See TracChangeset for help on using the changeset viewer.