Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion JCasADi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
<scripts>
<script>
<![CDATA[
project.properties.setProperty('native_script', project.properties.getProperty('always_recreate_wrapper') == 'true' ? '"${basedir}"/_regenerate-natives_dependency-recursive_Multiarch.sh' : '"${basedir}"/_ensure-natives_dependency-recursive_Multiarch.sh');
project.properties.setProperty('native_script', project.properties.getProperty('always_recreate_wrapper') == 'true' ? '${basedir}/_regenerate-natives_dependency-recursive_Multiarch.sh' : '${basedir}/_ensure-natives_dependency-recursive_Multiarch.sh');
println "native_script: " + project.properties.getProperty('native_script');
]]>
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,91 +1,154 @@
package de.dhbw.rahmlab.casadi;

import de.dhbw.rahmlab.casadi.api.core.wrapper.CoreWrapper;
import de.dhbw.rahmlab.casadi.impl.casadi.CodeGenerator;
import de.dhbw.rahmlab.casadi.impl.casadi.DM;
import de.dhbw.rahmlab.casadi.impl.casadi.Function;
import de.dhbw.rahmlab.casadi.impl.casadi.GenericType;
import de.dhbw.rahmlab.casadi.impl.casadi.Importer;
import de.dhbw.rahmlab.casadi.impl.casadi.MX;
import de.dhbw.rahmlab.casadi.impl.casadi.SX;
import de.dhbw.rahmlab.casadi.impl.std.Dict;
import de.dhbw.rahmlab.casadi.impl.std.StdVectorDM;
import de.dhbw.rahmlab.casadi.impl.std.StdVectorMX;
import de.dhbw.rahmlab.casadi.impl.std.StdVectorSX;

/**
* @author Oliver Rettig (Oliver.Rettig@orat.de)
*/
public class Demo8CodeGenerationSolution {

public static void main(String[] args) {



// Ex 1.1

SX x = SxStatic.sym("x", 2);
SX y = SxStatic.sym("y");

Function f = new Function("f", new StdVectorSX(new SX[]{x,y}),
new StdVectorSX(new SX[]{SxStatic.minus(SxStatic.sqrt(x),y)}));
Function f = new Function("f", new StdVectorSX(new SX[] { x, y }),
new StdVectorSX(new SX[] { SxStatic.minus(SxStatic.sqrt(x), y) }));
f.generate("fun");


// Ex 1.2

Dict options = new Dict();
options.put("with_header", new GenericType(true));

f.generate("fun2",options);


f.generate("fun2", options);

// %% Ex 1.3

MX xx = MxStatic.sym("x", 2);
MX yy = MxStatic.sym("y");

f = new Function("f", new StdVectorMX(new MX[]{xx, yy}),
new StdVectorMX(new MX[]{MxStatic.minus(MxStatic.sqrt(xx),yy)}));
f = new Function("f", new StdVectorMX(new MX[] { xx, yy }),
new StdVectorMX(new MX[] { MxStatic.minus(MxStatic.sqrt(xx), yy) }));

f.generate("fun3",options);
f.generate("fun3", options);

// % The function body (casadi_f0) changed a lot
// % f_work changed



// %% Ex 2.1

//TODO
/*qp = struct;
qp.h = Sparsity.dense(2, 2);
qp.a = Sparsity.dense(1,2);

f = conic("f","qrqp",qp);*/
// TODO
/*
* qp = struct;
* qp.h = Sparsity.dense(2, 2);
* qp.a = Sparsity.dense(1,2);
*
* f = conic("f","qrqp",qp);
*/
f.generate("fun21", options);

//TODO
//StdVectorDM args_1 = new StdVectorDM(new DM[]{new DM(posi_val), new DM(posi_des_val)});
// TODO
// StdVectorDM args_1 = new StdVectorDM(new DM[]{new DM(posi_val), new
// DM(posi_des_val)});

StdVectorMX result = new StdVectorMX();
// Funktionaufruf mit symbolischem Argument
//TODO
//f.call(args1, result);
//f("h",[1,0.3;0.3,7],"g",[2;3],"a",[1;2],"lba",-1,"uba",1)
// TODO
// f.call(args1, result);

// f("h",[1,0.3;0.3,7],"g",[2;3],"a",[1;2],"lba",-1,"uba",1)


// %% Ex 2.2

//TODO
//f = conic("f","osqp",qp);
f.generate("fun22",options);

//TODO
// TODO
// f = conic("f","osqp",qp);
f.generate("fun22", options);

// TODO
// das sollte sich mit java-board-Mitteln implementieren lassen

/*fileID = fopen("common.sh","w");
fprintf(fileID,"LIBDIR=''%s''\n",GlobalOptions.getCasadiPath());
fprintf(fileID,"INCDIR=''%s''\n",GlobalOptions.getCasadiIncludePath());
fclose(fileID);

fileID = fopen("common.bat","w");
fprintf(fileID,"set LIBDIR=%s\n",GlobalOptions.getCasadiPath());
fprintf(fileID,"set INCDIR=%s\n",GlobalOptions.getCasadiIncludePath());
fclose(fileID);*/

/*
* fileID = fopen("common.sh","w");
* fprintf(fileID,"LIBDIR=''%s''\n",GlobalOptions.getCasadiPath());
* fprintf(fileID,"INCDIR=''%s''\n",GlobalOptions.getCasadiIncludePath());
* fclose(fileID);
*
* fileID = fopen("common.bat","w");
* fprintf(fileID,"set LIBDIR=%s\n",GlobalOptions.getCasadiPath());
* fprintf(fileID,"set INCDIR=%s\n",GlobalOptions.getCasadiIncludePath());
* fclose(fileID);
*/

// Examples from https://web.casadi.org/docs/#generating-c-code
// 5.1 Syntax for generating code
SX x1 = SxStatic.sym("x");
SX y1 = SxStatic.sym("y");

Function f1 = new Function("f", new StdVectorSX(new SX[] { x1 }),
new StdVectorSX(new SX[] { SxStatic.sin(x1) }));
Function g1 = new Function("g", new StdVectorSX(new SX[] { y1 }),
new StdVectorSX(new SX[] { SxStatic.cos(y1) }));
Dict options1 = new Dict();
options1.put("with_header", new GenericType(true));
CodeGenerator C = new CodeGenerator("gen.c", options1);
C.add(f1);
C.add(g1);
C.generate();

// Compile c code to shared library (gen.so) using gcc
try {
ProcessBuilder pb = new ProcessBuilder("gcc", "-shared", "-fPIC", "-o", "gen.so", "gen.c");
Process process = pb.start();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}

// 5.2 Using the generated code (external function and JIT compilation)
long startTime = System.nanoTime();
Function fLoaded = CoreWrapper.external("f", "./gen.so").getCasADiObject();
StdVectorDM arg = new StdVectorDM(new DM[]{new DM(3.14)});
StdVectorDM res = new StdVectorDM();
fLoaded.call(arg, res);
long endTime = System.nanoTime();
System.out.println("Time taken to load and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fLoaded(3.14)="+res.toString()); // f(3.14)=[0.00159265]

Function gLoaded = CoreWrapper.external("g", "./gen.so").getCasADiObject();
gLoaded.call(arg, res);
System.out.println("gLoaded(3.14)="+res.toString()); // g(3.14)=[-0.999999]

startTime = System.nanoTime();
Importer cImporter = new Importer("gen.c", "shell"); // compiler can be "shell" or "clang" (CasADi distributed, but not working for JCasADi yet (2026-05-13))
Function fJIT = CoreWrapper.external("f", cImporter).getCasADiObject();
fJIT.call(arg, res);
endTime = System.nanoTime();
System.out.println("Time taken to JIT compile and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fJIT(3.14)="+res.toString()); // f(3.14)=[0.00159265]

// Use another optimization for JIT compilation from (https://github.com/casadi/casadi/issues/1941#issuecomment-274793064)
Dict jitOptions = new Dict();
jitOptions.put("flags", new GenericType("-O3"));
startTime = System.nanoTime();
Importer cImporter2 = new Importer("gen.c", "shell", jitOptions);
Function fJIT2 = CoreWrapper.external("f", cImporter2).getCasADiObject();
fJIT2.call(arg, res);
endTime = System.nanoTime();
System.out.println("Time taken to JIT compile with -O3 and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fJIT2(3.14)="+res.toString()); // f(3.14)=[0.00159265]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package de.dhbw.rahmlab.casadimaxima.api;

import de.dhbw.rahmlab.casadi.SxStatic;
import de.dhbw.rahmlab.casadi.api.core.wrapper.CoreWrapper;
import de.dhbw.rahmlab.casadi.impl.casadi.CodeGenerator;
import de.dhbw.rahmlab.casadi.impl.casadi.DM;
import de.dhbw.rahmlab.casadi.impl.casadi.Function;
import de.dhbw.rahmlab.casadi.impl.casadi.GenericType;
import de.dhbw.rahmlab.casadi.impl.casadi.Importer;
import de.dhbw.rahmlab.casadi.impl.casadi.SX;
import de.dhbw.rahmlab.casadi.impl.std.Dict;
import de.dhbw.rahmlab.casadi.impl.std.StdVectorDM;
import de.dhbw.rahmlab.casadi.impl.std.StdVectorSX;

public class DemoCodeGeneration {

public static void main(String[] args) {

// 5.1 Syntax for generating code
SX x1 = SxStatic.sym("x");
SX y1 = SxStatic.sym("y");

Function f1 = new Function("f", new StdVectorSX(new SX[] { x1 }),
new StdVectorSX(new SX[] { SxStatic.sin(x1) }));
Function g1 = new Function("g", new StdVectorSX(new SX[] { y1 }),
new StdVectorSX(new SX[] { SxStatic.cos(y1) }));
Dict options1 = new Dict();
options1.put("with_header", new GenericType(true));
CodeGenerator C = new CodeGenerator("gen.c", options1);
C.add(f1);
C.add(g1);
C.generate();

// Compile c code to shared library (gen.so) using gcc
try {
ProcessBuilder pb = new ProcessBuilder("gcc", "-shared", "-fPIC", "-o", "gen.so", "gen.c");
Process process = pb.start();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}

// 5.2 Using the generated code (external function and JIT compilation)
long startTime = System.nanoTime();
Function fLoaded = CoreWrapper.external("f", "./gen.so").getCasADiObject();
StdVectorDM arg = new StdVectorDM(new DM[] { new DM(3.14) });
StdVectorDM res = new StdVectorDM();
fLoaded.call(arg, res);
long endTime = System.nanoTime();
System.out.println("Time taken to load and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fLoaded(3.14)=" + res.toString()); // f(3.14)=[0.00159265]

Function gLoaded = CoreWrapper.external("g", "./gen.so").getCasADiObject();
gLoaded.call(arg, res);
System.out.println("gLoaded(3.14)=" + res.toString()); // g(3.14)=[-0.999999]

startTime = System.nanoTime();
Importer cImporter = new Importer("gen.c", "shell");
Function fJIT = CoreWrapper.external("f", cImporter).getCasADiObject();
fJIT.call(arg, res);
endTime = System.nanoTime();
System.out.println("Time taken to JIT compile and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fJIT(3.14)=" + res.toString()); // f(3.14)=[0.00159265]

Dict jitOptions = new Dict();
jitOptions.put("flags", new GenericType("-O3"));
startTime = System.nanoTime();
Importer cImporter2 = new Importer("gen.c", "shell", jitOptions);
Function fJIT2 = CoreWrapper.external("f", cImporter2).getCasADiObject();
fJIT2.call(arg, res);
endTime = System.nanoTime();
System.out.println("Time taken to JIT compile with -O3 and call f: " + (endTime - startTime) + " nanoseconds");
System.out.println("fJIT2(3.14)=" + res.toString()); // f(3.14)=[0.00159265]

// LaTeXify the symbolic expressions
long numberOfInputs = f1.n_in();
long numberOfOutputs = f1.n_out();
System.out.println("Function f has " + numberOfInputs + " input(s) and " + numberOfOutputs + " output(s).");
StdVectorSX fInSyms = f1.sx_in();
StdVectorSX fOutSyms = f1.sx_out();
SX[] fIns = new SX[10];
SX[] fOuts = new SX[10];
for (int i=0; i<f1.n_in() && i<10; i++) {
fIns[i] = fInSyms.get(0);
fOuts[i] = fOutSyms.get(0);
}

SX x = fIns[0];
SX sin = fOuts[0];

// TODO: Fix, because sin is only filled with placeholder by CasADi
// Function t = new Function("t", new StdVectorSX(new SX[]{x}), new StdVectorSX(new SX[]{sin}));
// t.call(arg, res);
// System.out.println(res.toString());

SX b1 = new SX(5,1);

System.out.println("LaTeX sin(x): " + MaximaLaTeXifier.LaTeXify(b1));

}
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Clone and build the Netbeans Maven project [JNativeLibLoader](https://github.com

## How to build
Open and build the Netbeans Maven project `./JCasADi`.
```bash
mvn clean package
```

The deployable jar should now be in the following path: `./JCasADi/target/JCasADi-1.0-SNAPSHOT-jar-with-dependencies.jar`.

Expand Down