brannonking / nloptnet Goto Github PK
View Code? Open in Web Editor NEWThis is a C# wrapper around the NLopt C library.
This is a C# wrapper around the NLopt C library.
Update NLoptNet to .NET standard 2.0 instead of the current .NET Framework 4.5.
Pull request #15 contains the update to .NET standard 2.0
Not sure what I am doing wrong, but all gradient based algorithms are stopping after one iteration (including your example). Those that do not use gradient information work fine.
AddLessOrEqualZeroConstraints(Action<double[], double[], double[]> constraints, double[] tolerances)
does not work as expected. When constraints
is called, the supplied double[] gradient
will have an incorrect length.
An mfunc is used here:
NLoptNet/NLoptNet/NLoptSolver.cs
Line 285 in a8561e5
mfunc is defined as:
NLoptNet/NLoptNet/NLoptSolver.cs
Line 47 in a8561e5
but the length of gradient
cannot be taken as SizeParamIndex = 2
when used in AddLessOrEqualZeroConstraints
. It is supposed to be m*n
. Any example with two or more constraints will break.
If updated from 1.3.0.0 to 1.4.0.0 and see these warnings (compiling to Any CPU):
Microsoft.Common.CurrentVersion.targets(2202, 5): [MSB3246] Resolved file has a bad image, no metadata, or is otherwise inaccessible. System.BadImageFormatException: Could not load file or assembly 'nlopt_x32.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
File name: 'nlopt_x32.dll' ---> System.BadImageFormatException: Could not load file or assembly 'nlopt_x32.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
File name: 'nlopt_x32.dll'
...
Also for nlopt_x64. It noticed that the lib folder of the package has changed that seems to cause this. Is this an unseen side effect of a change?
Here is the quite verbose warning:
Warning MSB3246 : Resolved file has a bad image, no metadata, or is otherwise inaccessible. System.BadImageFormatException: Could not load file or assembly 'nlopt_x64.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
File name: 'nlopt_x64.dll' ---> System.BadImageFormatException: Could not load file or assembly 'nlopt_x64.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
File name: 'nlopt_x64.dll'
at System.Reflection.AssemblyName.nGetFileInformation(String s)
at System.Reflection.AssemblyName.GetAssemblyName(String assemblyFile)
at Microsoft.Build.Shared.AssemblyNameExtension.GetAssemblyNameEx(String path)
at Microsoft.Build.Tasks.SystemState.GetAssemblyName(String path)
at Microsoft.Build.Tasks.ReferenceTable.SetPrimaryAssemblyReferenceItem(ITaskItem referenceAssemblyName)
Hi BrannonKing,
I made a small extension to your library in a local branch, which I would like push to Github and create a PR, but I think I do not have permission to do so?
(According to LGPL I need to make changes public so would prefer if I can just add them here instead of creating a fork. I guess you might also make a new Nuget package available at a certain point for other to use?)
Thanks,
Johan
I have n variables that I need to make binary, therefore I'm writing a simple constraint x[i]-x[i]^2=0
. I code it like this:
for (int i = 0; i < n; i++)
{
solver.AddEqualZeroConstraint(variables =>
{
return Math.Pow(variables[i], 2) - variables[i];
},0.01);
}
However, when I run it I get this exception:
System.ArgumentException: 'An item with the same key has already been added. Key: System.Func`2[System.Double[],System.Double]'
I'm adding the variable twice to the _funcCache
dictionary, anyone knows how to solve it?
I recently had a look at using NLOptNet - works very well out of the box in e.g. a .NET Core 3.1 test project.
However, when changing the target framework to .NET 4.7 I get:
System.DllNotFoundException : Unable to load DLL 'nlopt': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I've managed to solve this locally by adding a LoadLibrary step in a static constructor of the NLoptSolver class.
Happy to suggest these changes in a PR if there is interest - obviously realising that .NET Framework is not the future, and therefore may be less relevant to the community.
The __MonoCS__
predefine no longer works since Mono v5+. We need some other plan to make this work on Mono. Also, the runs for it in the Linux Action file are broken at present.
Hi,
Adding an equality constraint silently break the optimization. Independent variables becomes NaN
for all iteration steps (excepting the first one) breaking gradient computation too.
Below the minimal code that can be used to reproduce the behaviour.
public void TestSLSQP()
{
var gradientsHistory = new List<double[]>();
var variablesHistory = new List<double[]>();
double? finalScore;
NloptResult result;
using (var solver = new NLoptSolver(NLoptAlgorithm.LD_SLSQP, 2, maximumIterations: 20))
{
var initialValue = new[] { 1.234, 5.678 };
solver.SetLowerBounds(new[] { double.NegativeInfinity, 0.0000000000001 });
int count = 0;
solver.SetMinObjective((variables, gradient) =>
{
if (gradient != null)
{
gradient[0] = 0.0;
gradient[1] = variables[1];
}
count++;
var iterationGradients = new double[2];
Array.Copy(gradient, iterationGradients, 2);
gradientsHistory.Add(iterationGradients);
var iterationValues = new double[2];
Array.Copy(variables, iterationValues, 2);
variablesHistory.Add(iterationValues);
return variables[1];
});
// @BUG This is the line that broke everything
solver.AddEqualZeroConstraint(TestEq);
// @BUG This is the line that broke everything
result = solver.Optimize(initialValue, out finalScore);
}
}
private double TestEq(double[] values, double[] grads)
{
return values.Length + grads.Length;
}
Open for contribution...
Just a quick comment/issue, as it took me quite a while to figure this out in my code, maybe it will come in handy for anybody who reads this: right now the tolerance on the child algorithm can only be set when creating the NLOptSolver and will be set automatically as a relative tolerance on the variables change (which may or may not make sense).
When relativeStoppingTolerance is set to 0.0 (maybe because later on a relativeStoppingTolerance on the objective function is set), the algorithm will fail (or at least failed in my test cases).
Hi, more of a newbie question here. Are NLoptNet's .dll
files compiled and ready to use in Mac OS our would I need to do so on my computer? Thanks in advance!
The NLOptNet
DLL is not strongly named/signed. This is a problem for any strongly named project which tries to reference NLOptNet.dll
.
This can be changed in the project properties under "Signing -> Sign the assembly". Happy to submit a PR for this if it helps.
Please forgive me if this isn't the place to ask this question. I am trying to use this within Unity and my script fails to locate libnlopt-0.dll. Will this work as is within Unity?
I NuGet installed NLOptNet and copy/pasted some code from the ReadMe
When I execute the line:
var solver = new NLoptSolver(NLoptAlgorithm.LN_COBYLA, 1, 0.001, 100)
I get the below error
(Note: I am using .NET Framework 4.8. I also downloaded and installed https://github.com/stevengj/NLoptBuilder/releases/download/v2.6.1/NLopt.v2.6.1.x86_64-w64-mingw32.tar.gz and I even copied the libnlopt.dll from its bin directory to my executable directory and renamed it to nlopt_x64.dll.)
System.DllNotFoundException
HResult=0x80131524
Message=Unable to load DLL 'nlopt_x64.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Source=NLoptNet
StackTrace:
at NLoptNet.NLoptSolver.nlopt_create64(NLoptAlgorithm algorithm, UInt32 n)
at NLoptNet.NLoptSolver..ctor(NLoptAlgorithm algorithm, UInt32 numVariables, Double relativeStoppingTolerance, Int32 maximumIterations, Nullable`1 childAlgorithm)
Hi BrannonKing,
My virsus scanner indicated malware embedded in x64 libnlopt-0.dll bundled with version 1.0.2.0.
Hope this helps.
Best regards,
Jorrit
I have just been playing around with this wrapper and it looks like currently there is no way to add an equality constraint (I believe some algorithms treat these differently?). The underlying API is:
void nlopt::opt::add_equality_constraint(nlopt::vfunc h, void *h_data, double tol=0);
http://ab-initio.mit.edu/wiki/index.php/NLopt_C-plus-plus_Reference
I have had a brief look at the code, and importing the call looks like it shouldn't be too awkward
[DllImport("libnlopt-0.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern NloptResult nlopt_add_equality_constraint(IntPtr opt, nlopt_func h, IntPtr data, double tolerance);
Creating a new wrapper on the NLOptSolver I am not entirely sure about though. I assume we will need something like:
public void AddEqualityConstraint(Func<double[], double[], bool> constraint, double tolerance = 0.001)
{
nlopt_SomeNewfunc func = (u, values, gradient, data) => constraint.Invoke(values, gradient);
_funcCache.Add(constraint, func);
var res = nlopt_add_equality_constraint(_opt, func, IntPtr.Zero, tolerance);
if (res != NloptResult.SUCCESS)
throw new ArgumentException("Unable to add the constraint. Result: " + res, "constraint");
}
Curious if this is feasible.
Hi, I wanted to add a vector valued constraint, doesn't seem to work properly though. Basically it runs, but seems to ignore the constraints. Maybe related to that: what is the point of _funcCache? It seems, that it is never called or used? As this here requires an nlopt_mfunc, I had to change the dictionary type to <Delegate, Delegate>, would this cause the problem?
public void AddLessOrEqualZeroConstraints(Func<double[], double[]> constraint, uint m, double[] tolerances)
{
CheckInequalityConstraintAvailability();
nlopt_mfunc mfunc = (_m, result, _n, values, gradient, data) =>
{
if (gradient != null)
throw new InvalidOperationException("Expected the constraint to handle the gradient.");
result = constraint.Invoke(values);
};
_funcCache.Add(constraint, mfunc);
var res = nlopt_add_inequality_mconstraint(_opt, m, mfunc, IntPtr.Zero, tolerances);
if (res != NloptResult.SUCCESS)
throw new ArgumentException("Unable to add the constraint. Result: " + res, "constraint");
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.