/*::.
==================================================================================================================================
=================================================¦ Copyright © 2005 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       Finance.java
Originator: Allen Baker (2005.02.05)
LayoutRev:  5
================================================================================================================================== */



/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;



/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;



/*::
======================================================================================================================== *//**
This class provides static financial methods.<P>

These methods are based on the compound interest formula:

   <BLOCKQUOTE>
      <PRE id="unindent">
         fv = pv * ((1 + i) ^ n)

         where
            i = r / m
         and
            pv   Present Value (principle)
            fv   Future Value at end of n periods
            n    Number of compounding periods
            m    number of compounding periods per year
            i    Interest rate per compounding period
            r    annual interest Rate (nominal rate)

         also indirectly derivable from this formula are the following:

            er   effective annual interest Rate (effective rate)
                    When interest is compounded at a frequency of any other than
                    1 compounding period per year, the stated annual rate is
                    called a "nominal rate". The simple interest rate that would
                    produce the same interest using a compounding period of 1
                    time per year is called the "effective rate". The effective
                    rate is used to compare various types of investments.
      </PRE>
   </BLOCKQUOTE>

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  =========================================================================================
                  What is the annual interest rate (r) on an investment of $120.00 (pv)
                  that is worth $131.68 (fv) after 60 compounding periods (n) where
                  there are 12 compounding periods per year (m) -- that is, 5 years
                  compounded monthly.
                  -----------------------------------------------------------------------------------------
                  double r = r(120, 131.68, 60, 12);
                  System.out.println("r   =   " + UMath.toPct(r) + "%");

                  =========================================================================================
                  whats the er
                  -----------------------------------------------------------------------------------------
                  double er = er(120, 131.68, 60, 12);
                  System.out.println("er  =   " + UMath.toPct(er) + "%");

                  =========================================================================================
                  Check the above computation by finding what an investment of $120.00
                  (pv) is worth (fv) after 60 compounding periods (n) where there are
                  12 compounding periods per year (m) -- that is, 5 years compounded
                  monthly -- and the annual interest rate is the rate computed above
                  (r). The computation of r above is verified if the fv calculated
                  here is $131.68.
                  -----------------------------------------------------------------------------------------
                  System.out.println("fv  =  $" + fv(120, 60, 12, r));

                  =========================================================================================
                  Check using the er
                  -----------------------------------------------------------------------------------------
                  System.out.println("fv  =  $" + fv(120, 5, 1, er));
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="Finance.java.html">
               Finance.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class Finance
   {



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Inner Classes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Static Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes fv from pv, n, m, and r.<P>

   This method is based on solving the compound interest formula for fv:

      <BLOCKQUOTE>
         <PRE id="unindent">
            fv = pv * ((1 + i) ^ n)
            fv = pv * ((1 + (r/m)) ^ n)
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#000">View source</A>

   @return
      Fv - Future Value at end of n periods

   @param
      Pv Present Value (principle)
   @param
      N Number of copounding periods
   @param
      M number of compounding periods per year
   @param
      R annual interest Rate
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double fv(double pv, double n, double m, double r)
      {
      double fv = pv * UMath.pow(1+(r/m),n);
      return UMath.round(fv,5);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes pv from fv, n, m, and r.<P>

   This method is based on solving the compound interest formula for pv:

      <BLOCKQUOTE>
         <PRE id="unindent">
            fv                      =  pv * ((1 + i) ^ n)
            fv / ((1 + i) ^ n)      =  pv
            fv / ((1 + (r/m)) ^ n)  =  pv
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#001">View source</A>

   @return
      Pv - Present Value (principle)

   @param
      Fv Future Value at end of n periods
   @param
      N Number of copounding periods
   @param
      M number of compounding periods per year
   @param
      R annual interest Rate
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double pv(double fv, double n, double m, double r)
      {
      double pv = fv / UMath.pow(1+(r/m),n);
      return UMath.round(pv,5);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes I from pv, fv, and n.<P>

   This method is based on solving the compound interest formula for i:

      <BLOCKQUOTE>
         <PRE id="unindent">
            *                          fv  =  pv * ((1 + i) ^ n)
            *                   (fv / pv)  =  ((1 + i) ^ n)
            *         (fv / pv) ^ (1 / n)  =  (1 + i)
            *   ((fv / pv) ^ (1 / n)) - 1  =  i
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#002">View source</A>

   @return
      I - Interest rate per compounding period

   @param
      Pv Present Value (principle)
   @param
      Fv Future Value at end of n periods
   @param
      N Number of copounding periods
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double i(double pv, double fv, double n)
      {
      double i = (UMath.pow((fv/pv),(1.0/n)) - 1.0);
      return i;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes I from m and r.

      <BLOCKQUOTE>
         <PRE id="unindent">
            i = (r / m)
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#003">View source</A>

   @return
      I - Interest rate per compounding period

   @param
      M number of compounding periods per year
   @param
      R annual interest Rate
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double i(double m, double r)
      {
      double i = (r / m);
      return i;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes r from pv, fv, n, and m.<P>

   This method is based on solving the compound interest formula for r:

      <BLOCKQUOTE>
         <PRE id="unindent">
            *                                fv  =  pv * ((1 + i) ^ n)
            *                         (fv / pv)  =  ((1 + i) ^ n)
            *               (fv / pv) ^ (1 / n)  =  (1 + i)
            *         ((fv / pv) ^ (1 / n)) - 1  =  i
            *         ((fv / pv) ^ (1 / n)) - 1  =  (r / m)
            *   (((fv / pv) ^ (1 / n)) - 1) * m  =  r
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#004">View source</A>

   @return
      R - annual interest Rate

   @param
      Pv Present Value (principle)
   @param
      Fv Future Value at end of n periods
   @param
      N Number of copounding periods
   @param
      M number of compounding periods per year
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double r(double pv, double fv, double n, double m)
      {
      double r = (UMath.pow((fv/pv),(1.0/n)) - 1.0) * m;
      return r;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes er from pv, fv, n, and m.

   <P><B>Implementation: </B><A HREF="Finance.java.html#005">View source</A>

   @return
      Er - effective annual interest Rate (effective rate)

   @param
      Pv Present Value (principle)
   @param
      Fv Future Value at end of n periods
   @param
      N Number of copounding periods
   @param
      M number of compounding periods per year
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double er(double pv, double fv, double n, double m)
      {
      double r = r(pv, fv, n / m, 1);
      return r;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method computes n from pv, fv, m, and r.<P>

   This method is based on solving the compound interest formula for n:

      <BLOCKQUOTE>
         <PRE id="unindent">
            using these facts about logarithms:

               x = log[b](y) <--> y = b^x            (see: http://www.math.utah.edu/~alfeld/math/log.html)

               log[a](b) = log[10](b) / log[10](a)   (see: http://en.wikipedia.org/wiki/Logarithm#Change_of_base)

            Solve for n:

                   fv  =  pv * ((1 + i) ^ n)
            (fv / pv)  =  ((1 + i) ^ n)
                    n  =  log[1 + i](fv / pv)
                    n  =  log[10](fv / pv) / log[10](1 + i)
                    n  =  log[10](fv / pv) / log[10](1 + (r / m))
         </PRE>
      </BLOCKQUOTE>

   <P><B>Implementation: </B><A HREF="Finance.java.html#006">View source</A>

   @return
      N - Number of copounding periods

   @param
      Pv Present Value (principle)
   @param
      Fv Future Value at end of n periods
   @param
      M number of compounding periods per year
   @param
      R annual interest Rate
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static double n(double pv, double fv, double m, double r)
      {
      double n = UMath.log10(fv / pv) / UMath.log10(1 + (r / m));
      return UMath.round(n,0);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method allows the Finance class file to be unit tested as a standalone application. It's the
   method that's called when the class is invoked from the command line by using the java application
   launcher - "java". Main() is not a required method, but the practice of putting one in each class
   and wrapping class test code within it allows easy unit testing of the class; and main does not need
   to be removed when testing is complete.

   <P>
      <DL>
         <DT>
            <B>
               Command line usage:
            </B>
            <DD>
               Java cosmicabyss.com.lib.Finance
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="Finance.java.html#007">View source</A>

   @param
      pArgs contains the command line arguments with which the class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      System.out.println();

      /*.
      ==========================================================================================
      What is the annual interest rate (r) on an investment of $120.00 (pv) that is worth
      $131.68 (fv) after 60 compounding periods (n) where there are 12 compounding periods per
      year (m) -- that is, 5 years compounded monthly.
      ------------------------------------------------------------------------------------------ */
      double r = r(120, 131.68, 60, 12);
      System.out.println("r   =   " + UMath.toPct(r) + "%");
      /*.
      ==========================================================================================
      Whats the er
      ------------------------------------------------------------------------------------------ */
      double er = er(120, 131.68, 60, 12);
      System.out.println("er  =   " + UMath.toPct(er) + "%");
      /*.
      ==========================================================================================
      Check the above computation by finding what an investment of $120.00 (pv) is worth (fv)
      after 60 compounding periods (n) where there are 12 compounding periods per year (m) --
      that is, 5 years compounded monthly -- and the annual interest rate is the rate computed
      above (r). The computation of r above is verified if the fv calculated here is $131.68.
      ------------------------------------------------------------------------------------------ */
      System.out.println("fv  =  $" + fv(120, 60, 12, r));
      /*.
      ==========================================================================================
      Check using the er
      ------------------------------------------------------------------------------------------ */
      System.out.println("fv  =  $" + fv(120, 5, 1, er));

      System.out.println();
      /*.
      ==========================================================================================
      Figure out Hillary's interest rate on cattle futures. PV=1000, FV=100000, N=0.83333, M=1
      ------------------------------------------------------------------------------------------ */
      System.out.println("PV=1000, FV=100000, N=0.83333, M=1, i=" + i(1, 2, 0.833333));
      System.out.println("PV=1000, N=0.83333, M=1, i=250.18919839969, FV=" + fv(1000, 0.833333, 1, 250.18919839969));
      System.out.println("FV=14000000, N=0.83333, M=1, i=250.18919839969, PV=" + pv(14000000, 0.833333, 1, 250.18919839969));
      }



   }  // class Finance