// Copyright (C) 2004, 2006 International Business Machines and others.
// All Rights Reserved.
// This code is published under the Eclipse Public License.
//
// Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13

#include "IpMatrix.hpp"

namespace Ipopt
{
void Matrix::AddMSinvZ(
   Number        alpha,
   const Vector& S,
   const Vector& Z,
   Vector&       X
) const
{
   AddMSinvZImpl(alpha, S, Z, X);
}

void Matrix::SinvBlrmZMTdBr(
   Number        alpha,
   const Vector& S,
   const Vector& R,
   const Vector& Z,
   const Vector& D,
   Vector&       X
) const
{
   SinvBlrmZMTdBrImpl(alpha, S, R, Z, D, X);
}

// Prototype for specialize methods (can and should be overloaded)
void Matrix::AddMSinvZImpl(
   Number        alpha,
   const Vector& S,
   const Vector& Z,
   Vector&       X
) const
{
   SmartPtr<Vector> tmp = S.MakeNew();
   tmp->AddVectorQuotient(1., Z, S, 0.);
   MultVector(alpha, *tmp, 1., X);
}

void Matrix::SinvBlrmZMTdBrImpl(
   Number        alpha,
   const Vector& S,
   const Vector& R,
   const Vector& Z,
   const Vector& D,
   Vector&       X
) const
{
   TransMultVector(alpha, D, 0., X);
   X.ElementWiseMultiply(Z);
   X.Axpy(1., R);
   X.ElementWiseDivide(S);
}

bool Matrix::HasValidNumbers() const
{
   if( valid_cache_tag_ != GetTag() )
   {
      cached_valid_ = HasValidNumbersImpl();
      valid_cache_tag_ = GetTag();
   }
   return cached_valid_;
}

void Matrix::Print(
   SmartPtr<const Journalist> jnlst,
   EJournalLevel              level,
   EJournalCategory           category,
   const std::string&         name,
   Index                      indent,
   const std::string&         prefix
) const
{
   if( IsValid(jnlst) && jnlst->ProduceOutput(level, category) )
   {
      PrintImpl(*jnlst, level, category, name, indent, prefix);
   }
}

void Matrix::Print(
   const Journalist&  jnlst,
   EJournalLevel      level,
   EJournalCategory   category,
   const std::string& name,
   Index              indent,
   const std::string& prefix
) const
{
   if( jnlst.ProduceOutput(level, category) )
   {
      PrintImpl(jnlst, level, category, name, indent, prefix);
   }
}

} // namespace Ipopt
