gmsk is an unofficial wrapper for MOSEK, the conic optimizer from MOSEK ApS.
For Detailed Documentation, See Go Reference
See Examples section on Go Reference for many examples reproduced from C api code.
Hello World example from C api is provided below.
package main import ( "fmt" "log" "github.com/fardream/gmsk" ) // This is reproduced from MOSEK C example hellowworld.c // However, the response code is checked here. func main() { checkOk := func(err error) { if err != nil { log.Fatalf("failed: %s", err.Error()) } } task, err := gmsk.MakeTask(nil, 0, 0) if err != nil { log.Fatal(err) } defer gmsk.DeleteTask(task) checkOk(task.AppendVars(1)) checkOk(task.PutCJ(0, 1.0)) checkOk(task.PutVarBound(0, gmsk.BK_RA, 2.0, 3.0)) checkOk(task.PutObjSense(gmsk.OBJECTIVE_SENSE_MINIMIZE)) _, res := task.OptimizeTrm() checkOk(res) result := make([]float64, 1) result, res = task.GetXx(gmsk.SOL_ITR, result) fmt.Printf("Solution x = %.6f\n", result[0]) }
GMSK requires the C api for MOSEK, which can be obtained from MOSEK's website. To actually build the package, a recent enough C toolchain, and the environment should be properly set up.
On linux, this can be achieved by setting CPATH environment variable and LIBRARY_PATH
# prepend mosek header folder to CPATH, replace {version} and {arch} with the one you have installed export CPATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/h${CPATH:+":${CPATH}"} # prepend mosek lib folder to LIBRARY_PATH export LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LIBRARY_PATH:+":${LIBRARY_PATH}"} export LD_LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}
Alternatively, this can set up for cgo specifically
export CGO_CFLAGS="-I${MSKHOME}/mosek/{version}/tools/platform/{arch}/h" export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"
IF LD_LIBRARY_PATH doesn't include MOSEK's binary folder when running the code, the binary can be set up by adding MOSEK's binary folder to rpath, for example, the CGO_LDFLAGS can be updated to add rpath
export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin -Wl,-rpath=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"
Follow the installation instructions on MOSEK's website - remember to run install.py. Note unless System Integrity Protect (SIP) is turned off on macOS, the environment variable LD_LIBRARY_PATH (and macOS specific DYLD_LIBRARY_PATH) will NOT work.
When building, the setup is similar to linux
# prepend mosek header folder to CPATH, replace {version} and {arch} with the one you have installed export CPATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/h${CPATH:+":${CPATH}"} # prepend mosek lib folder to LIBRARY_PATH export LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LIBRARY_PATH:+":${LIBRARY_PATH}"}
or
export CGO_CFLAGS="-I${MSKHOME}/mosek/{version}/tools/platform/{arch}/h" export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"
However, the binary may not be able to find libmosek at runtime. Besides default search path, macOS will also look for dynlib in the rpaths of the binary - however, it only does so if the load path of the dynlib starts with @rpath - which is controlled by the LC_ID_DYLIB of the dynlib (in this case, libmosek64).
So there are two options
-
Use
rpath. First addrpathto the linker lineexport CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin -Wl,-headerpad,128 -Wl,-rpath,${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin" #
Then check
LC_ID_DYNLIBon thelibmosek64.dynlib, and update it withinstall_name_tool(which is part of Apple's development suite). For example, for 10.0 version of the libraryinstall_name_tool -id @rpath/libmosek64.10.0.dynlib path/to/libmosek64.10.0.dynlib
-
Change
LC_ID_DYNLIBto the full absolute path oflibmosek64.install_name_tool -id /abspath/to/libmosek64.10.0.dynlib path/to/libmosek64.10.0.dynlib