This question already has an answer here:
Establish Units of Measure Relationships With a Quantity of Another Unit
(1 answer)
Closed 5 years ago.
It would be great to be able to auto-convert units of measure, which are just multipliers of the same dimension. (kg -> g, cm -> mm, km -> m). From what I've read online:
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure
https://fsharpforfunandprofit.com/posts/units-of-measure/
I doesn't seem possible to have this working without helper functions. From my view, those conversions pollute the computations. I want something like this to work:
[<Measure>] type m
[<Measure>] type km = 1000 * m
The below wouldn't work either.
let distance = 1000 * 10**3 <m>
Is this achievable in some other way?
I don't know F#, but yeah, units polute computations. That's why you should convert values only during input (eg. reading form file/stdin), do calculations always in the same units, metric system is a go in here. Then, at the end, convert the result from metric system to whatever unit you want.
That way it's very easy to add support for new unit later on
Related
There does not seem to be an "easy" way (such as in R or python) to create interaction terms between dummy variables in gretl ?
Do we really need to code those manually which will be difficult for many levels? Here is a minimal example of manual coding:
open credscore.gdt
SelfemplOwnRent=OwnRent*Selfempl
# model 1
ols Acc 0 OwnRent Selfempl SelfemplOwnRent
Now my manual interaction term will not work for factors with many levels and in fact does not even do the job for binary variables.
Thanks,
ML
One way of doing this is to use lists. Use the dummify-command for generating dummies for each level and the ^-operator for creating the interactions. Example:
open griliches.gdt
discrete med
list X = dummify(med)
list D = dummify(mrt)
list INT = X^D
ols lw 0 X D INT
The command discrete turns your variable into a discrete variable and allows to use dummify (this step is not necessary if your variable is already discrete). Now all interactions terms are stored in the list INT and you can easily assess them in the following ols-command.
#Markus Loecher on your second question:
You can always use the rename command to rename a series. So you would have to loop over all elements in list INT to do so. However, I would rather suggest to rename both input series, in the above example mrt and med respectively, before computing the interaction terms if you want shorter series names.
I am quite new with F# and still trying to decide what the best structure for my financial (back testing) program should be.
As data are immutable, I am thinking that "heavy"/all-in-one structures might not be ideal.
Here is what I try to achieve:
A backtesting engine which creates a strategy every business days.
The strategy consists of a few instruments with a seq/list of trades
(trading date / quantity / price)
I then run calculation (value, risks etc) daily on all those positions for each portfolio. I also add trades to each instruments each day as I adjust the position.
How I first constructed it:
List or seq of dates: [D1 .. Dn]
List or seq of Portfolio Pi [P1 .. Pn] (with several instruments). Each portoflio will start its life at a different Di
For each portfolio, I will have some daily trades on the instrusments
when I compute value, profit and losses, risks ...
What I have used for now (very simplified):
type Instrument1 = {
some specifications
}
type Instrument2 = {
some specifications
}
type Instrument =
| Inst1 of Instrument1
| Inst2 of Instrument2
type Trade = {
Dt ; DateTime
Qty : float
Price : float }
type Portfolio = {
InitDate : DateTime // one of the Di above
Inst : Instruments
Trades : Trade seq }
type BackTesting =
Dates : DateTime seq
Port : Portfolio seq }
And then I create a seq (Dates) of seq (Portfolio) of seq (Instrument) showing let's say P&L.
However, for each portfolio Pi I am iterating on all dates to check if I need to adjust the portfolio and then add a trade to the trade list, it means that every day, for every portfolio, for every instrument, I am creating a new BackTesting (non mutable). I believe this way of reasoning is way more OOP than FP but I am a bit lost on proper patterns to use (the F# books I have used are not very clear on the data structure that works best for FP - or I did not really understand them).
I might not be very clear but if anyone has a direction into which I should look at (or any useful documentation/support on the issue), please do not hesitate. Thanks a lot for your help.
Since you are starting with F#, my suggestion to you is to not worry too much about programming in a purely functional way. If you come from an imperative style of programming it may be too much of a change and you may be discouraged. The shift from imperative style to functional style takes time and it's gradual.
The good thing is F# lets you be imperative too!
So program like you would in other languages:
Use global mutable variables when it best suits you.
Use for and while
Did you know that array elements are mutable?
As you progress you will learn the functional way, some things are really easy to use
right away:
Definitely use option, never null
Try using map, filter, choose over list, array or seq.
In time you will naturally gravitate more towards the functional style but you don't have to jump all at once. One of the best resources to get started is https://fsharpforfunandprofit.com/ its full of very good articles, slides, videos conveyed in a clear way.
Good luck!
Hello I can calculate 17^1000 in calculator of windows 7 and it looks like
1.2121254521552524e+123 (which seems to me to be not correct)
how can I write it in delphi and I want to use for example 1.2121254521552524e+123 mod 18
or 1.2121254521552524e+123 mod 100.
Another example: 17 mod 5 = 2
How can I write it can anyone help me?
You would need to use some sort of extended precision type. Such a type would not be a primitive type, you would need to either use an existing one or write your own (which would be a huge amount of work, and a classic case of reinventing the wheel). Java might be a better language for this because its system libraries include BigInteger and BigDecimal classes, which handle the functionality you would need.
Edit: Here are some delphi libraries providing large integer and high precision floating point arithmetic: http://www.delphiforfun.org/programs/Library/big_integers.htm
That said, if you find yourself unable to use the windows calculator to accomplish what you are looking for and you only need this for one or two things, consider using a more powerful online service such as WolframAlpha.
Also, in case you still don't have an answer:
17^1000 mod 18 == 1
17^1000 mod 100 == 1
The algorithm used to compute numbers like these is simple and does not require large integer support. Consider the following pseudocode:
modular_exponentiation (base, exponent, modulus):
let value = 1
let c_exponent = 0
for c_exponent less than exponent:
let value = value * base
if value greater than or equal to modulus:
let value = (value) mod (modulus)
increment c_exponent
value.
I use the following PLINQ-implemented parallel map function.
let parmap f (xs:list<_>) = xs.AsParallel().Select(fun x -> f x) |> Seq.toList
I want to improve my speedup on 4 cores which I'm not able to get above 2. I found one can do custom partitioning to improve the parallel performance. But I have seen C# examples mainly and not sure how to get it to work with F#. The following doesn't change anything but then I think it is the default partitioning used by TPL? How can I use the different (static, dynamic,...) partitioning options here?
let pmap_plinqlst_parts f (xs:list<_>) =
let parts = Partitioner.Create(xs)
parts.AsParallel().Select(fun x -> f x) |> Seq.toList
Typically a custom partitioner would be used if the work units were extremely small. When faced with this problem you may be better off switching to Task rather than Async as its generally more suited to smaller but more numerous amounts of work, with Async being more suited to IO type operations where the latency would be typically longer.
For example you would batch up calculations in sequences amongst parallel threads. The yield would vary depending on the size of the work units and also the number of total items.
There is no limit to scaling in any of the methods you mentioned. I parallelised a Black Scholes calculation and managed to get around 6.8x on an 8 core machine using Async.Parallel. Although not a perfect mechanism I used a simple division of work amongst the initial sequences that were passed to Async.Parallel.
Are you sure you have a true four core machine or a two core machine with hyper threading?
AFAIK, Currency type in Delphi Win32 depends on the processor floating point precision. Because of this I'm having rounding problems when comparing two Currency values, returning different results depending on the machine.
For now I'm using the SameValue function passing a Epsilon parameter = 0.009, because I only need 2 decimal digits precision.
Is there any better way to avoid this problem?
The Currency type in Delphi is a 64-bit integer scaled by 1/10,000; in other words, its smallest increment is equivalent to 0.0001. It is not susceptible to precision issues in the same way that floating point code is.
However, if you are multiplying your Currency numbers by floating-point types, or dividing your Currency values, the rounding does need to be worked out one way or the other. The FPU controls this mechanism (it's called the "control word"). The Math unit contains some procedures which control this mechanism: SetRoundMode in particular. You can see the effects in this program:
{$APPTYPE CONSOLE}
uses Math;
var
x: Currency;
y: Currency;
begin
SetRoundMode(rmTruncate);
x := 1;
x := x / 6;
SetRoundMode(rmNearest);
y := 1;
y := y / 6;
Writeln(x = y); // false
Writeln(x - y); // 0.0001; i.e. 0.1666 vs 0.1667
end.
It is possible that a third-party library you are using is setting the control word to a different value. You may want to set the control word (i.e. rounding mode) explicitly at the starting point of your important calculations.
Also, if your calculations ever transfer into plain floating point and then back into Currency, all bets are off - too hard to audit. Make sure all your calculations are in Currency.
No, Currency is not a floating point type. It is a fixed-precision decimal, implemented with integer storage. It can be compared exactly, and does not have the rounding issues of, say, Double. Therefore, if you are seeing inexact values in your Currency variables, the problem is not the Currency type itself, but what you are putting into it. Most likely, you have a floating-point calculation somewhere else in your code. Since you do not show that code, it's hard to be of more help on this question. But the solution, generally speaking, will be to round your floating point numbers to the correct precision before storing in the Currency variable, rather than doing an inexact comparison on the Currency variables.
Faster and safer way of comparing two currency values is certainly to map the variables to their internal Int64 representation:
function CompCurrency(var A,B: currency): Int64;
var A64: Int64 absolute A;
B64: Int64 absolute B;
begin
result := A64-B64;
end;
This will avoid any rounding error during comparison (working with *10000 integer values), and will be faster than the default FPU-based implementation (especially under 64 bit XE2 compiler).
See this article for additional information.
If your situation is like mine, you might find this approach helpful. I work mostly in payroll. If a business has say 3 departments and wants to charge the cost of an employee evenly among those three departments, there are a lot of times when there will be rounding issues.
What I have been doing is loop through the departments charging each one a third of the total cost and adding the cost charged to a subtotal (currency) variable. But when the loop variable equals the limit, rather than multiplying by the fraction, I subtract the subtotal variable from the total cost and put that in the last department. Since the journal entries that result from this process always have to balance, I believe that it has always worked.
See thread:
D7 / DUnit: all CheckEquals(Currency, Currency) tests suddenly fail ...
https://forums.codegear.com/thread.jspa?threadID=16288
It looks like a change on our development workstations caused Currency comparision to fail. We have not found the root cause, but on two computers running Windows 2000 SP4, and independent of the version of gds32.dll (InterBase 7.5.1 or 2007) and Delphi (7 and 2009), this line
TIBDataBase.Create(nil);
changes the value of to 8087 control word from $1372 to $1272 now.
And all Currency comparisions in unit tests will fail with funny messages like
Expected: <12.34> - Found: <12.34>
The gds32.dll has not been modified, so I guess that there is a dependency in this library to a third party dll which modifies the control word.
To avoid possible issues with currency rounding in Delphi use 4 decimal places.
This will ensure that you never having rounding issues when doing calcualtions with very small amounts.
"Been there. Done That. Written the unit tests."