balForcing ::
  (Ord node, Show node,
   Sweep.SweepClass sweep vec a,
   Arith.Sum (sweep vec a),
   Sweep.SweepMap sweep vec a a,
   Arith.Constant a) =>
  Balance.Forcing node a ->
  Params.Optimisation node list sweep vec a ->
  Type.StoragePowerMap node sweep vec a ->
  Result (sweep vec a)
balForcing balanceForcing params powerMap =
  Map.foldWithKey f zero (Balance.unForcingMap balanceForcing)
      where
        zero = Determined $ Sweep.fromRational (Params.sweepLength params) Arith.zero
        f stoNode forcingFactor acc = g acc force
          where
            g (Determined ac) (Determined fo) = Determined $ ac ~+ fo
            g _ _ = Undetermined

            force = fmap (Sweep.map (Balance.getSocDrive forcingFactor ~*)) stoPower

            stoPower =
              fromMaybe (error $ "forcing failed, because node not found: " ++ show stoNode)
                        (join $ Map.lookup stoNode powerMap)
balForcing ::
  (Ord node, Show node,
   Sweep.SweepClass sweep vec a,
   Arith.Sum (sweep vec a),
   Sweep.SweepMap sweep vec a a,
   Arith.Constant a) =>
  Balance.Forcing node a ->
  Params.Optimisation node list sweep vec a ->
  Type.StoragePowerMap node sweep vec a ->
  Result (sweep vec a)
balForcing balanceForcing params powerMap =
  Map.foldWithKey f zero (Balance.unForcingMap balanceForcing)
      where
        zero = Determined $ Sweep.fromRational (Params.sweepLength params) Arith.zero
        f stoNode forcingFactor acc = g acc force
          where
            g (Determined ac) (Determined fo) = Determined $ ac ~+ fo
            g _ _ = Undetermined

            force = fmap (Sweep.map (Balance.getSocDrive forcingFactor ~*)) stoPower

            stoPower =
              fromMaybe (error $ "forcing failed, because node not found: " ++ show stoNode)
                        (join $ Map.lookup stoNode powerMap)
balForcing balanceForcing params powerMap =
  Map.foldWithKey f zero (Balance.unForcingMap balanceForcing)
      where
        zero = Determined $ Sweep.fromRational (Params.sweepLength params) Arith.zero
        f stoNode forcingFactor acc = g acc force
          where
            g (Determined ac) (Determined fo) = Determined $ ac ~+ fo
            g _ _ = Undetermined

            force = fmap (Sweep.map (Balance.getSocDrive forcingFactor ~*)) stoPower

            stoPower =
              fromMaybe (error $ "forcing failed, because node not found: " ++ show stoNode)
                        (join $ Map.lookup stoNode powerMap)