- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I'm facing an issue when doing an itrative sum using factorials. This is the first time I use both an iterative sum and the FACT function so I guess there are a lot of things wrong in my code.
Want I want is the formula I hereby attached.
Here it its:
data lsv.right;
set lsv.left;
do i=0 to i=(buy+sell);
right = ((fact(buy+sell)/ (fact(i)+fact(Buy+sell-i)))*(i/(buy+sell))*((1-Pt)**(Buy+sell-i))*abs((i/(buy+sell)-Pt)))+ right;
end;
run;
Here is a sample of data I have. BUy and sell are integers.
Buy | Sell | Pt | Right |
3 | 4 | 2,7865 | |
8 | 10 | 6,78783 |
Could you please help me with it ?
Thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So what is the problem with it, is it giving an Error/Warning or not giving you the result you expect. If you are not getting the result you expect then break the formula down into parts, e.g.:
data ...;
temp1=fact(buy+sell);
temp2=temp1 /....
If it is error/warning then post the log.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Here is the log error message
NOTE: Invalid argument to function FACT at line 36 column 11.
NOTE: Invalid argument to function FACT at line 36 column 36.
NOTE: Invalid argument to function FACT at line 36 column 11.
NOTE: Invalid argument to function FACT at line 36 column 36.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Well, I would first check that all your variables are numeric (I suspect this is your problem). Buy, sell and pt. If not then you are passing a character to a function which is requiring a numeric. I would also re-iterate to break the formula up so you have a bit more clarity of what is going on (this works for me), like:
data have;
attrib Buy Sell Pt format=best.;
buy=3; sell=4; pt=27865; output;
buy=8; sell=10; pt=678783; output;
run;
data want;
set have;
bs=buy + sell;
right=0;
do i=0 to bs;
calc1=(fact(bs) / (fact(i) + fact(bs-i)));
calc2=calc1 * (i/(bs)) * ((1-Pt)**(bs-i)) * abs((i/(bs)-Pt));
right=calc2 + right;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Wild guess, that 'buy' and/or 'sell' are character variables in dataset lsv.left as mentioned by , judging by the location in the line for these NOTEs..
You may wish to consider reparameterizing and using LFACT (log of the factorial) in order to avoid a noncomputable result for moderately large arguments.
Steve Denham
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I used your code and I made sure that I treat with numeric variables. I create a num variable n that is the sum of buy and sell. But it still shows the same log error
Proc SQL;
alter table lsv.left
add n num label='n';
Proc SQL;
update lsv.left
set n=buy+sell;
data lsv.right;
set lsv.left;
right=0;
do i=0 to i=n;
calc1=(fact(n) / (fact(i) * fact(n-i)));
calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));
right=calc2 + right;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
In your code you have:
do I=0 to I=n;
This is incorrect, you want a range, so I=0 to n;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, I corrected it and nows the log error message becomes
Invalid DO loop control information, either the INITIAL or TO expression is missing or the
BY expression is missing, zero, or invalid.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Check what N in lsv.left as it sound like that is not being create properly. So do this:
Run the first SQL statement, check the lsv.left. Does this look correct.
Run the second SQL statement, check the lsv.left table looks correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I did it and there actually was a problem. The fact is that n was worth '.' when there were a buy or sell =0. So I corrected it this way
Proc SQL;
update lsv.left
set n=buy where sell=.;
Proc SQL;
Update lsv.left
set n=sell where buy=.;
But I still have the same error message
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Could you post some test data of lsv.left after the two proc sql statements have run. I suspect you still have a . or missing in your data i.e. what happens if both buy and sell are missing, then that row should be removed as the procedures cannot work on that data.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Maybe get rid of the SQL part and just add a clause in your datastep:
data lsv.right;
set lsv.left;
right=0;
if buy ne . or sell ne . then do;
if buy=. then n=sell;
else n=buy;
do i=0 to i=n;
calc1=(fact(n) / (fact(i) * fact(n-i)));
calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));
right=calc2 + right;
end;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot ! YOu were right. One row had both sell and buy equal to .
i deleted it and now it's working, thanks a lot !
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately i'm still facing an issue I can't solve; The value I otain for right is always >1 and sometimes superhigh. In actual facts this formula always lead to a result <1.
FYI: the input Pt is always around 0,5
Do you have an idea of the problem in the code ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, am a code monkey not a stato, its all greek to me. Maybe post a question in the stats section.