Microsoft Solver Foundation and F# - f#
I'm trying to convert this MS Solver Foundation example from C# to F#, but constantly running into problems with type conversions, in particular in section 5, where C# accepts implicit conversion from double to Rational, something F# does not accept - any ideas how to resolve? The Rational type in itself is a puzzle for me as seems virtually impossible to initialize apart from setting it to the predefined Rational.One or Rational.Zero. Any ideas? See a minimalist down-scaled version below (without using any arrays or anything).
let main argv =
printfn "%A" argv
Console.WriteLine("\nBegin Solver demo\n")
let mean = 1.0
let solver = new InteriorPointSolver()
let allocation = ref 0
solver.AddVariable("MSFT", allocation) |> ignore
solver.SetBounds(!allocation, Rational.Zero, Rational.One)
let expRet = ref 0
solver.AddRow("expRet", expRet) |> ignore
solver.SetBounds(!expRet, Rational.Zero, Rational.PositiveInfinity)
let unity = ref 0
solver.AddRow("Investments sum to one", unity) |> ignore
solver.SetBounds(!unity, Rational.One, Rational.One)
solver.SetCoefficient(!expRet, !allocation, Rational.)
solver.SetCoefficient(!unity, !allocation, Rational.One);
Console.WriteLine("\nEnd Solver demo\n")
Console.ReadLine() |> ignore
0 // return an integer exit code
This is an old post, but no one has answered, and this information may be useful to others.
I don't know F# (so anyone who does, please edit my syntax), but the following methods in the Rational class should be of use. You will also need the BigInteger class from the Microsoft.SolverFoundation.Common name space.
(see https://learn.microsoft.com/en-us/previous-versions/visualstudio/ff526610)
First, as you point out, you can construct a Rational directly from other types using any of the many "implicit" constructors:
let Rational rat5 = Rational.op_Implicit(5.0:float)
let Rational rat2 = Rational.op_Implicit(2:int)
where I am guessing F# syntax.
As another quite illustrative example, monetary values (e.g. $10.43) can rarely be represented exactly with doubles. (The only "cents" values that wind up exact in a double are xx.00, xx.25, xx.50 and xx.75, all others wind up with numerical errors/differences.) So we often have to be careful when constructing a rational from a double that purports to represent a monetary value. This provides a good sample of another method of constructing rationals:
let BigInteger bi100 = BigInteger.op_Implicit(100:int)
let float mv = 1000000000000.43 //I am assuming this gets classified by F# as a double.
//Now, we assume mv is any double that represents a monetary value, and so should be an even 2 decimal places in base 10
//I have no idea how to Round in F#, nor how to cast to an integer - I have guessed - but should illustrate the idea if it is not valid F#
let BigInteger cents = BigInteger.op_Implicit( ( Round(mv * 100.0) ):int ) //get exact monetary value, in cents
let Rational ratMv = Rational.Get(cents:BigInteger, bi100:BigInteger)
and so we have constructed a Rational, from two BigInteger types, that exactly represents a monetary value mv stored as a double.
Here is the entire Rational interface, albeit in c#-syntax:
namespace Microsoft.SolverFoundation.Common
{
[CLSCompliant(true)]
public struct Rational : IComparable, IComparable<Rational>, IEquatable<Rational>, IComparable<BigInteger>, IEquatable<BigInteger>, IComparable<int>, IEquatable<int>, IComparable<uint>, IEquatable<uint>, IComparable<long>, IEquatable<long>, IComparable<ulong>, IEquatable<ulong>, IComparable<double>, IEquatable<double>
{
public static readonly Rational NegativeInfinity;
public static readonly Rational Zero;
public static readonly Rational One;
public static readonly Rational PositiveInfinity;
public static readonly Rational Indeterminate;
public static readonly Rational UnsignedInfinity;
public bool IsOne { get; }
public bool IsFinite { get; }
public bool IsIndeterminate { get; }
public bool IsInfinite { get; }
public bool IsSignedInfinity { get; }
public bool IsUnsignedInfinity { get; }
public bool HasSign { get; }
public bool IsNegativeInfinity { get; }
public bool IsZero { get; }
public int BitCount { get; }
public int Sign { get; }
public BigInteger Numerator { get; }
public bool IsPositiveInfinity { get; }
public BigInteger Denominator { get; }
public Rational AbsoluteValue { get; }
public static Rational AddMul(Rational ratAdd, Rational ratMul1, Rational ratMul2);
public static Rational Get(BigInteger bnNum, BigInteger bnDen);
public static void Negate(ref Rational num);
public static bool Power(Rational ratBase, Rational ratExp, out Rational ratRes);
public void AppendDecimalString(StringBuilder sb, int cchMax);
public int CompareTo(BigInteger bn);
[CLSCompliant(false)]
public int CompareTo(uint u);
public int CompareTo(Rational rat);
public int CompareTo(long nn);
[CLSCompliant(false)]
public int CompareTo(ulong uu);
public int CompareTo(double dbl);
public int CompareTo(int n);
public int CompareTo(object obj);
[CLSCompliant(false)]
public bool Equals(uint u);
public bool Equals(Rational rat);
public bool Equals(long nn);
[CLSCompliant(false)]
public bool Equals(ulong uu);
public bool Equals(int n);
public bool Equals(BigInteger bn);
public override bool Equals(object obj);
public bool Equals(double dbl);
public Rational GetCeiling();
public Rational GetCeilingResidual();
public Rational GetFloor();
public Rational GetFloorResidual();
public Rational GetFractionalPart();
public override int GetHashCode();
public Rational GetIntegerPart();
public double GetSignedDouble();
public Rational Invert();
public bool IsInteger(out BigInteger bn);
public bool IsInteger();
public double ToDouble();
public override string ToString();
public static Rational operator +(Rational rat1, Rational rat2);
public static Rational operator -(Rational rat);
public static Rational operator -(Rational rat1, Rational rat2);
public static Rational operator *(Rational rat1, Rational rat2);
public static Rational operator /(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator ==(uint n, Rational rat);
[CLSCompliant(false)]
public static bool operator ==(Rational rat, uint n);
public static bool operator ==(int n, Rational rat);
public static bool operator ==(long n, Rational rat);
public static bool operator ==(Rational rat, BigInteger bn);
public static bool operator ==(Rational rat, int n);
public static bool operator ==(Rational rat, long n);
public static bool operator ==(BigInteger bn, Rational rat);
public static bool operator ==(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator ==(Rational rat, ulong n);
public static bool operator ==(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator ==(ulong n, Rational rat);
public static bool operator ==(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator !=(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator !=(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator !=(uint n, Rational rat);
public static bool operator !=(BigInteger bn, Rational rat);
[CLSCompliant(false)]
public static bool operator !=(Rational rat, uint n);
public static bool operator !=(double dbl, Rational rat);
public static bool operator !=(int n, Rational rat);
public static bool operator !=(Rational rat, int n);
public static bool operator !=(long n, Rational rat);
public static bool operator !=(Rational rat, BigInteger bn);
public static bool operator !=(Rational rat1, Rational rat2);
public static bool operator !=(Rational rat, double dbl);
public static bool operator !=(Rational rat, long n);
public static bool operator <(double dbl, Rational rat);
public static bool operator <(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator <(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator <(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator <(uint n, Rational rat);
public static bool operator <(Rational rat1, Rational rat2);
public static bool operator <(Rational rat, BigInteger bn);
public static bool operator <(long n, Rational rat);
public static bool operator <(BigInteger bn, Rational rat);
public static bool operator <(Rational rat, int n);
public static bool operator <(int n, Rational rat);
[CLSCompliant(false)]
public static bool operator <(Rational rat, uint n);
public static bool operator <(Rational rat, long n);
public static bool operator >(long n, Rational rat);
public static bool operator >(Rational rat1, Rational rat2);
public static bool operator >(Rational rat, BigInteger bn);
public static bool operator >(BigInteger bn, Rational rat);
public static bool operator >(Rational rat, int n);
[CLSCompliant(false)]
public static bool operator >(Rational rat, uint n);
public static bool operator >(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator >(uint n, Rational rat);
public static bool operator >(int n, Rational rat);
public static bool operator >(Rational rat, long n);
public static bool operator >(Rational rat, double dbl);
[CLSCompliant(false)]
public static bool operator >(ulong n, Rational rat);
[CLSCompliant(false)]
public static bool operator >(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator <=(ulong n, Rational rat);
public static bool operator <=(Rational rat, int n);
public static bool operator <=(Rational rat, BigInteger bn);
public static bool operator <=(int n, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(Rational rat, uint n);
public static bool operator <=(BigInteger bn, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(Rational rat, ulong n);
public static bool operator <=(Rational rat1, Rational rat2);
public static bool operator <=(long n, Rational rat);
public static bool operator <=(Rational rat, double dbl);
public static bool operator <=(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator <=(uint n, Rational rat);
public static bool operator <=(Rational rat, long n);
public static bool operator >=(Rational rat, BigInteger bn);
public static bool operator >=(Rational rat1, Rational rat2);
[CLSCompliant(false)]
public static bool operator >=(Rational rat, ulong n);
[CLSCompliant(false)]
public static bool operator >=(uint n, Rational rat);
public static bool operator >=(Rational rat, long n);
public static bool operator >=(int n, Rational rat);
public static bool operator >=(BigInteger bn, Rational rat);
public static bool operator >=(Rational rat, int n);
[CLSCompliant(false)]
public static bool operator >=(ulong n, Rational rat);
public static bool operator >=(long n, Rational rat);
public static bool operator >=(double dbl, Rational rat);
[CLSCompliant(false)]
public static bool operator >=(Rational rat, uint n);
public static bool operator >=(Rational rat, double dbl);
public static implicit operator Rational(double dbl);
public static implicit operator Rational(BigInteger bn);
[CLSCompliant(false)]
public static implicit operator Rational(uint u);
public static implicit operator Rational(long nn);
[CLSCompliant(false)]
public static implicit operator Rational(ulong uu);
public static implicit operator Rational(int n);
public static explicit operator BigInteger(Rational rat);
public static explicit operator double(Rational rat);
[CLSCompliant(false)]
public static explicit operator ulong(Rational rat);
public static explicit operator long(Rational rat);
[CLSCompliant(false)]
public static explicit operator uint(Rational rat);
public static explicit operator int(Rational rat);
}
}
The other very useful bit of information that can be found at the above link is this table:
"The following table lists how special cases of rational numbers are represented.
Rational number
Representation
Non-zero finite rational values
(numerator, denominator) with denominator > 0
Zero
(0, 0)
Negative infinity
(-1, 0)
Positive infinity
(+1, 0)
Unsigned infinity
(+2, 0)
Indeterminate (NaN)
(+3, 0)
Dividing a nonzero value by zero results in unsigned infinity because 0 is unsigned. Dividing a finite value by any infinite value results in 0."
Related
Tree of unary operators
I want to parse expressions like a ++a a++ ++a++ ++a++++ The pre-increment operator has precedence over the post-increment operator. The parsers I have are these: public static readonly TokenListParser<LangToken, UnaryOperator> Increment = Token.EqualTo(LangToken.DoublePlus).Select(x => UnaryOperators.Increment); public static readonly TokenListParser<LangToken, UnaryOperator> Decrement = Token.EqualTo(LangToken.DoubleMinus).Select(x => UnaryOperators.Decrement); public static readonly TokenListParser<LangToken, Expression> Identifier = Token.EqualTo(LangToken.Identifier).Select(x => (Expression)new Id(x.ToStringValue())); public static readonly TokenListParser<LangToken, Expression> A = from c in Parse.Ref(() => Expression) from op in Increment.Or(Decrement) select (Expression)new OpNode(op, c); public static readonly TokenListParser<LangToken, Expression> B = from op in Increment.Or(Decrement) from c in Parse.Ref(() => Expression) select (Expression)new OpNode(op, c); public static readonly TokenListParser<LangToken, Expression> Expression = A.Or(B).Or(Identifier); However, when I parse a simple expression like "a++" using the Expression parser, the test hangs. I suppose that it's due to a recursion problem. But what's the problem and how to solve it?
Why does F# compiler prefer to generate closed implementations of FSharpFunc types?
For this code: module Module = let func x y z = 0 [<EntryPoint>] let main args = func 1 func 1 1 0 Decompilation yields: [CompilationMapping(SourceConstructFlags.Module)] public static class Main { [CompilationMapping(SourceConstructFlags.Module)] public static class Module { [Serializable] internal sealed class main#30 : OptimizedClosures.FSharpFunc<object, object, int> { [DebuggerBrowsable(DebuggerBrowsableState.Never)] [CompilerGenerated] [DebuggerNonUserCode] public int x; [CompilerGenerated] [DebuggerNonUserCode] internal main#30(int x) { this.x = x; } public override int Invoke(object y, object z) { return func(x, y, z); } } [Serializable] internal sealed class main#31-1 : FSharpFunc<object, int> { [DebuggerBrowsable(DebuggerBrowsableState.Never)] [CompilerGenerated] [DebuggerNonUserCode] public int x; [DebuggerBrowsable(DebuggerBrowsableState.Never)] [CompilerGenerated] [DebuggerNonUserCode] public int y; [CompilerGenerated] [DebuggerNonUserCode] internal main#31-1(int x, int y) { this.x = x; this.y = y; } public override int Invoke(object z) { return func(x, y, z); } } [CompilationArgumentCounts(new int[] { 1, 1, 1 })] public static int func<a, b, c>(a x, b y, c z) { return 0; } [EntryPoint] public static int main(string[] args) { int x = 1; new main#30(x); int x2 = 1; int y = 1; new main#31-1(x2, y); return 0; } } public static a Dump<a>(a arg00) { return arg00.Dump(); } } It generates a concrete type, that is generic parameters are provided at type definition. Why is not this done at the point of construction? I also noticed that types are generated in the module where call occurs, not where func is defined. Having let func x y z = ... we need implementations of types to cover all possibilities: FSharpFunc<T1,FSharpFunc<T2,T3,TReturn>> FSharpFunc<T1,T2,FSharpFunc<T3,TReturn>> FSharpFunc<T1,FSharpFunc<T2,FsharpFunc<T3,TReturn>>> Compiler could generate all possible combinations in the same place, where function is defined, closing only for parameters with inferenced types. You could argue that for the list of 7 args the set of types going to be quite large, but types like FSharpFunc<T1,T2,..,Tn, FSharpFunc<...>> are a mere optimazation. And FSharpFunc supports up to six generic types, then compiler has to switch to FSharpFun<T1,T2,T3,T4,T5,FSharp<...>>.
As pointed out by Fyodor it's not function creation that makes the compiler generating the hidden classes. The hidden classes are used to implement partial application. In F# a partial application and lambdas are implemented as a compiler generated class that extends an abstract class. C# lambdas rely on delegates instead. IIRC Java and Scala use a similar technique to F# as JVM doesn't have delegates. I suspect the F# compiler generates a class per partial application because it's simpler than collecting all partial applications and coalesce the identical ones. It also helps the debuggability of F# programs as the name hints where the partial application was done: main#31-1 => In the main function at row 31. This name if included in logs or performance runs can help identifying what partial application is causing problems. This comes at the cost of increasing the size of the F# assembly file as noted in a comment by Pavel.
Virtual function overloading and signature
I thought that since f's argument is float - the float version of f will be called, but that's not the case. Why is it? Thank you! class A { public: virtual void f(int n) { cout<<"A"<<endl; } }; class B: public A { public: virtual void f(float f) { cout<<"B"<<endl; } }; int main() { A* ptr = new B; ptr->f(6.66); delete ptr; }
Retrieving item text with JNA and SendMessage()
I am attempting to retrieve the item text from a Win32 ListView-like control. I am using JNA and SendMessageW() to send LVM_GETITEMTEXTW to the control. I have been successful at retrieving the item count (via LVM_GETITEMCOUNT) but am stumped at this point. My User32 class is setup like so: public interface MyUser32 extends User32 { MyUser32 INSTANCE = (MyUser32)Native.loadLibrary("user32", MyUser32.class); LRESULT SendMessageW(HWND hWnd, int msg, WPARAM wParam, LVITEM lParam); } My LVITEM class is setup like so: public class LVITEM extends Structure{ public LVITEM() { pszText = new Memory(MEMSIZE); cchTextMax = MEMSIZE; } private static final int MEMSIZE = 256; public UINT mask; public int iItem; public int iSubItem; public UINT state; public UINT stateMask; public Pointer pszText; public int cchTextMax; public int iImage; public LPARAM lParam; public int iIndent; protected List<String> getFieldOrder() { return Arrays.asList(new String[] { "mask", "iItem", "iSubItem", "state", "stateMask", "pszText", "cchTextMax", "iImage", "lParam", "iIndent"}); } } And the code that calls it all is like so: MyUser32 u32 = MyUser32.INSTANCE; LVITEM lvItem = new LVITEM(); WPARAM wPar = new WPARAM(1); ... lvItem.iSubItem = 0; res = u32.SendMessageW(handle, LVM_GETITEMTEXTW, wPar, lvItem); System.out.println(res.intValue()); s = lvItem.pszText.getString(0); System.out.println(s); I've left out a bit of the code but I believe those are the important parts. My issue is that when I print out res.intValue() it is always 0 (meaning no text was returned) and when I print out the string value of pszText it is always some garbage characters. I'm completely stumped at this point so any suggestions are greatly appreciated. Thanks.
How to Convert a C++ Structure into C# Structure
I need to convert a complex C++ structure into C# Structure,I have converted other structures in C#, this one contains some Two Dimensional array that is what the problem how to change it,Here is my structure, this is other structure, which I Converted properly, C++: typedef struct { BYTE sSerialNumber[DH_SERIALNO_LEN]; BYTE byAlarmInPortNum; BYTE byAlarmOutPortNum; BYTE byDiskNum; BYTE byDVRType; BYTE byChanNum; } NET_DEVICEINFO, *LPNET_DEVICEINFO; C#: public struct NET_DEVICEINFO { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] sSerialNumber; public byte byAlarmInPortNum; public byte byAlarmOutPortNum; public byte byDiskNum; public byte byDVRType; public byte byChanNum; } And This structure Which I want Convert,this has 2 dim Array C++: typedef struct { DWORD dwSize; DWORD dwDecProListNum; char DecProName[DH_MAX_DECPRO_LIST_SIZE][DH_MAX_NAME_LEN]; DH_485_CFG stDecoder[DH_MAX_DECODER_NUM]; DWORD dw232FuncNameNum; char s232FuncName[DH_MAX_232FUNCS][DH_MAX_NAME_LEN]; DH_RS232_CFG st232[DH_MAX_232_NUM]; } DHDEV_COMM_CFG; and this is my try in C#,But it is giving me an error, C#: [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Auto)] public struct DHDEV_COMM_CFG { public uint dwSize; public uint dwDecProListNum; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] public string[] DecProName; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] DH_485_CFG[] stDecoder; public uint dw232FuncNameNum; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public string[] s232FuncName; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public DH_RS232_CFG[] st232; } ; Please tell me how to to this.... By Bala
I know this is kinda useless 6 years down the road, but in any case, the converter from here worked nicely for me...