Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / August 2006

Tip: Looking for answers? Try searching our database.

Formula calculation C# code needed

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
GB - 30 Aug 2006 06:12 GMT
Hello,
How to calculate value for the following formula (I need C# code):

res = (((m+1)(m+2)...(m+(k-1)))/1.2...(k-1))

or more generalized formula is:

          k-1
           __
           |  | (m+i)
           i=1
res = ---------------
          k-1
          __
          |  | i
          i=1

Thanks,
GB
Jon Skeet [C# MVP] - 30 Aug 2006 07:14 GMT
> Hello,
> How to calculate value for the following formula (I need C# code):
[quoted text clipped - 12 lines]
>            |  | i
>            i=1

Well, why not just do the calculation in a loop? Loop round doing the
multiplication, then loop round doing the division. You'll lose a fair
amount of precision, but that may be okay depending on what your use
is...

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

GB - 30 Aug 2006 07:26 GMT
Please, give me an example.

GB
>> Hello,
>> How to calculate value for the following formula (I need C# code):
[quoted text clipped - 17 lines]
> amount of precision, but that may be okay depending on what your use
> is...
Ben Newsam - 30 Aug 2006 09:47 GMT
>Please, give me an example.
>
[quoted text clipped - 15 lines]
>>>            |  | i
>>>            i=1

Let me get this right...

In your example, say, if m=3 and k=10, and i=1 (is i *always* 1?),
then you need to calculate:

(4.5.6.7.8.9) / (1.2.3.4.5.6.7.8.9), which works out at 0.16667 (same
as 1/6)

and  m=4 and k=9 would be (5.6.7.8)/(1.2.3.4.5.6.7.8), which is
0.041667

If this is correct, then I would do it recursively:

long MyFunc ( long n, long Limit, long i )
{
    long Result = n;
    if ( n <= Limit )
        return Result;
    return ( n * MyFunc ( n - i, Limit, i ) );
}

Then you can do:

           long k = 10;
           long m = 3;
           long i = 1;
           double res1 = 0.0, res2 = 0.0;
           double result = 0.0;

           res1 = (double) MyFunc(k - 1, m + 1, i);
           res2 = (double) MyFunc(k - 1, 1, 1);
           result = res1 / res2;

and
           k = 9;
           m = 4;
           res1 = (double) MyFunc(k - 1, m + 1, i);
           res2 = (double) MyFunc(k - 1, 1, 1);
           result = res1 / res2;

The last one gives 0.041666...664
Oh well, it's close.

Signature

Posted via a free Usenet account from http://www.teranews.com

DaanishRumani - 30 Aug 2006 10:44 GMT
I would do it this way.

// Numerator
double Pi_MplusI(int start, int end, int m)
{
  double result = 1.0;

  if(start > end)
  {
     // swap start and end
     int temp = start;
     start = end;
     end = temp;
  }

  if(start == end)
  {
     // not sure about this!!!
     return 1.0;
  }

  for(int i= start; i < end; ++i)
  {
     result *= m + i;
  }

  return result;
}

// Denominator
double Pi_I(int start, int end)
{
  double result = 1.0;

  if(start > end)
  {
     // swap start and end
     int temp = start;
     start = end;
     end = temp;
  }

  if(start == end)
  {
     // not sure about this!!!
     return 1.0;
  }

  for(int i= start; i < end; ++i)
  {
     result *= i;
  }

  return result;
}

// Result
double res(int i, int m)
{
  double result = 1.0;
  int i;
  int k;
  int m;

  // get your values here
  i = 1;
  k = 10;
  m = 100;

  result = Pi_MplusI(1, k) / Pi_I(1, k);

  return result;
}
Marc Gravell - 30 Aug 2006 10:59 GMT
actually, if my math is right that would be 4.5.6.7.8.9.10.11.12 /
1.2.3.4.5.6.7.8.9, leaving 10.11.12 / 1.2.3, leaving 220 [i is just the
product-indexer in the range 1 to k-1 inclusive]

Perhaps the trick here is to look for those terms that are not cancelled;
you could probably do this by looking at the figures and doing a lot of
thinking, but you'd need to think for each and every formula; how about this
instead? It detects cancelled terms before they are multiplied (reducing
both rounding error and the FLOP count), and could be applied to any such
formula.

Marc

class Product {
       // dictionary key is the factor, value is the power
       readonly Dictionary<int, int> factors = new Dictionary<int, int>();
       public void Multiply(int factor) {
           int power;
           factors.TryGetValue(factor, out power);
           factors[factor] = power + 1;
       }
       public void Divide(int quotient) {
           int power;
           factors.TryGetValue(quotient, out power);
           factors[quotient] = power - 1;
       }
       public double Evaluate() {
           // could also perhaps do with logarithms?
           double result = 1.0;
           foreach (KeyValuePair<int, int> pair in factors) {
               int power = pair.Value;
               if (power == 0) continue; // nothing to do
               result *= Math.Pow(pair.Key, power);
           }
           return result;
       }

   }
   static class Program {
       static void Main() {
           int k = 10, m = 3;
           Product p = new Product();
           // could actually do both loops at once, but
           // keep it simple for easy re-use with different
           // maths...
           for(int i = 1; i <= k - 1; i++) {
               p.Multiply(m+i);
           }
           for (int i = 1; i <= k - 1; i++) {
               p.Divide(i);
           }
           MessageBox.Show(p.Evaluate().ToString());
       }
   }
Marc Gravell - 30 Aug 2006 11:18 GMT
Some refinements below:
* handles zero multipliers much more efficiently (short-circuits everything)
* throws exception on zero quotients
* tracks "sign" separately, so that -17 can cancel 17
* discards "unit" (but tracks sign)
* performs single * and / directly, to avoid a Math.Pow() call

Marc

class Product {
       readonly Dictionary<int, int> factors = new Dictionary<int, int>();
       bool zero = false, negate = false;
       public void Multiply(int factor) {
           if (zero) return;
           if (factor == 0) {
               zero = true;
               factors.Clear();
               return; // all over
           }
           if (factor < 0) {
               negate = !negate;
               factor = -factor;
           }
           if (factor == 1) { // unit
               return; // nothing more to do
           }
           int power;
           factors.TryGetValue(factor, out power);
           factors[factor] = power + 1;
       }
       public void Divide(int quotient) {
           if (quotient == 0) throw new DivideByZeroException();
           if (zero) return;
           if (quotient < 0) {
               negate = !negate;
               quotient = -quotient;
           }
           if (quotient == 1) { // unit
               return; // nothing more to do
           }
           int power;
           factors.TryGetValue(quotient, out power);
           factors[quotient] = power - 1;
       }
       public double Evaluate() {
           if (zero) return 0;
           // could also perhaps do with logarithms?
           double result = 1.0;
           foreach (KeyValuePair<int, int> pair in factors) {
               int factor = pair.Key, power = pair.Value;
               switch (power) {
                   case 0: break; // do nothing (cancelled factor)
                   case 1: result *= factor; break; // single mult
                   case -1: result /= factor; break; // single div
                   default: result *= Math.Pow(factor, power); break; //
everything else
               }
           }
           return negate ? -result : result;
       }
   }
Rick Lones - 30 Aug 2006 13:01 GMT
So you are evalulating C(m+k-1, k-1), the number of combinations of (m+k-1)
things taken (k-1) at a time, correct?

Then you want:

Prod((m+1),(m+k-1)) / Prod(1, (k-1)), where:

(warning, untested code!)

long Prod(int low, int high)
{
    long result = low;
    int  multiplier = low;

    while (++multiplier <= high)
        result *= multiplier;

    return result;
}

HTH,
-rick-

> Hello,
> How to calculate value for the following formula (I need C# code):
[quoted text clipped - 15 lines]
> Thanks,
> GB
GB - 30 Aug 2006 17:02 GMT
Thank you , Rick.
It works perfectly for me!

GB

2
> So you are evalulating C(m+k-1, k-1), the number of combinations of (m+k-1)
> things taken (k-1) at a time, correct?
[quoted text clipped - 38 lines]
> > Thanks,
> > GB

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.