Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d35fc52

Browse filesBrowse files
committed
add Black-Scholez example
1 parent 2af37e1 commit d35fc52
Copy full SHA for d35fc52

File tree

Expand file treeCollapse file tree

11 files changed

+132
-43
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

11 files changed

+132
-43
lines changed
Open diff view settings
Collapse file

‎src/symjava/bytecode/TestByteCode.java‎

Copy file name to clipboardExpand all lines: src/symjava/bytecode/TestByteCode.java
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package symjava.bytecode;
22

33
public class TestByteCode {
4-
public double fun(double[] args) {
4+
public static double fun(double[] args) {
55
// return args[0] + args[1];
66
double s = Math.pow(2, 3);
77
return s;
Collapse file

‎src/symjava/domains/Interval.java‎

Copy file name to clipboardExpand all lines: src/symjava/domains/Interval.java
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public Interval(Expr start, Expr end) {
1616
}
1717

1818
public Interval(Expr start, Expr end, Expr coordVar) {
19-
super("["+start+","+end+"]", x);
19+
super("["+start+","+end+"]", coordVar);
2020
this.start = start;
2121
this.end = end;
2222
}
Collapse file

‎src/symjava/examples/BlackScholez.java‎

Copy file name to clipboardExpand all lines: src/symjava/examples/BlackScholez.java
+19-18Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
public class BlackScholez {
1313

1414
public static void main(String[] args) {
15-
// TODO Auto-generated method stub
16-
Symbol spot = new Symbol("spot");
17-
Symbol strike = new Symbol("strike");
15+
//Construct the Balck-Scholez equation
16+
Symbol spot = new Symbol("spot"); //spot price
17+
Symbol strike = new Symbol("strike"); //strike price
1818
Symbol rd = new Symbol("rd");
1919
Symbol rf = new Symbol("rf");
20-
Symbol vol = new Symbol("\\sigma");
20+
Symbol vol = new Symbol("\\sigma"); //volatility
2121
Symbol tau = new Symbol("\\tau");
2222
Symbol phi = new Symbol("\\phi");
2323

@@ -28,34 +28,35 @@ public static void main(String[] args) {
2828

2929
Expr dp = (log(fwd/strike)+0.5*pow(stdDev,2))/stdDev;
3030
Expr dm = (log(fwd/strike)-0.5*pow(stdDev,2))/stdDev;
31-
System.out.println(dp);
32-
System.out.println(dm);
3331

34-
Domain I1 = Interval.apply(-oo, phi*dp, z);
32+
//Domain I1 = Interval.apply(-oo, phi*dp, z);
33+
Domain I1 = Interval.apply(-10, phi*dp, z); //Good enough for -10, it will take a long time to use -oo
3534
Expr cdf1 = Integrate.apply(exp(-0.5*pow(z,2)), I1)/sqrt(PI2);
36-
Domain I2 = Interval.apply(-oo, phi*dm, z);
35+
36+
//Domain I2 = Interval.apply(-oo, phi*dm, z);
37+
Domain I2 = Interval.apply(-10, phi*dm, z);
3738
Expr cdf2 = Integrate.apply(exp(-0.5*pow(z,2)), I2)/sqrt(PI2);
3839

3940
Expr res = phi*domDf*(fwd*cdf1-strike*cdf2);
40-
System.out.println(res);
41-
42-
System.out.println(res.diff(vol));
41+
System.out.println("Balck-Scholez equation:");
42+
System.out.println(res+"\n");
43+
System.out.println("The first derivative of Balck-Scholez equation with respect to volatility \\sigma:");
44+
System.out.println(res.diff(vol)+"\n"); //Let computer do it for us.
4345

44-
45-
// Calculate Black-Scholes price for a given vol
46+
// Calculate Black-Scholes price for a given volatility: \sigma=0.1423
4647
BytecodeFunc blackScholesPrice = JIT.compile(new Expr[]{spot, strike, rd, rf, vol, tau, phi}, res);
4748
double price = blackScholesPrice.apply(100.0, 110.0, 0.002, 0.01, 0.1423, 0.5, 1);
4849

49-
System.out.println("Newtom method:");
50+
System.out.println("Use Newtom method to recover the volatility by given the market data:");
5051
Expr[] freeVars = {vol};
51-
Expr[] params = {spot, strike, rd, rf, tau, phi};
52+
Expr[] params = {spot, strike, rd, rf, tau, phi}; //Specify the params in the given order
5253
Eq[] eq = new Eq[] {
53-
new Eq(res-price, C0, freeVars, params)
54+
new Eq(res-price, C0, freeVars, params)
5455
};
5556

5657
double[] guess = new double[]{ 0.10 };
57-
58-
Newton.solve(eq, guess, 1000, 1e-5);
58+
double[] constParams = new double[] {100.0, 110.0, 0.002, 0.01, 0.5, 1};
59+
Newton.solve(eq, guess, constParams, 1000, 1e-5);
5960
}
6061

6162
}
Collapse file

‎src/symjava/examples/Example3.java‎

Copy file name to clipboardExpand all lines: src/symjava/examples/Example3.java
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static void example1() {
1414
Expr[] freeVars = {x};
1515
double num = 612;
1616
Eq[] eq = new Eq[] {
17-
new Eq(x*x-num, C0, freeVars, null)
17+
new Eq(x*x-num, C0, freeVars)
1818
};
1919

2020
double[] guess = new double[]{ 10 };
Collapse file

‎src/symjava/examples/Newton.java‎

Copy file name to clipboardExpand all lines: src/symjava/examples/Newton.java
+33-6Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@
1515
*/
1616
public class Newton {
1717
public static void solve(Eq[] eqs, double[] init, int maxIter, double eps) {
18+
solve(eqs, init, new double[0], maxIter, eps);
19+
}
20+
21+
public static void solve(Eq[] eqs, double[] init, double[] params, int maxIter, double eps) {
1822
for(Eq eq : eqs) {
1923
if(!Symbol.C0.symEquals(eq.rhs)) {
2024
System.out.println("The right hand side of the equation must be 0.");
2125
return;
2226
}
2327
}
2428
Expr[] unknowns = eqs[0].getUnknowns();
29+
Expr[] funParams = eqs[0].getParams();
30+
if(funParams.length != params.length) {
31+
throw new RuntimeException("funParams.length != params.length");
32+
}
2533
int m = eqs.length;
2634
int n = unknowns.length;
2735

@@ -40,24 +48,43 @@ public static void solve(Eq[] eqs, double[] init, int maxIter, double eps) {
4048
System.out.println(hess);
4149

4250
//Convert symbolic staff to Bytecode staff to speedup evaluation
43-
NumMatrix NH = new NumMatrix(hess, unknowns);
44-
NumVector NG = new NumVector(lhss, unknowns);
51+
Expr[] args = new Expr[unknowns.length + funParams.length];
52+
int ii=0;
53+
for(int j=0; j<unknowns.length; j++)
54+
args[ii++] = unknowns[j];
55+
for(int j=0; j<funParams.length; j++)
56+
args[ii++] = funParams[j];
57+
NumMatrix NH = new NumMatrix(hess, args);
58+
NumVector NG = new NumVector(lhss, args);
4559

4660
System.out.println("Iterativly sovle ... ");
61+
double[] funArgs = new double[args.length];
62+
for(int j=0; j<init.length;j++)
63+
funArgs[j] = init[j];
64+
for(int j=init.length; j<funArgs.length; j++)
65+
funArgs[j] = params[j-init.length];
66+
4767
for(int i=0; i<maxIter; i++) {
4868
//Use JAMA to solve the system
49-
Matrix A = new Matrix(NH.eval(init));
50-
Matrix b = new Matrix(NG.eval(init), NG.dim());
69+
Matrix A = new Matrix(NH.eval(funArgs));
70+
// System.out.println("Matrix:");
71+
// for(int j=0;j<A.getRowDimension();j++) {
72+
// for(int k=0; k<A.getColumnDimension(); k++) {
73+
// System.out.println(A.get(j,k)+" ");
74+
// }
75+
// System.out.println();
76+
// }
77+
Matrix b = new Matrix(NG.eval(funArgs), NG.dim());
5178
Matrix x = A.solve(b); //Lease Square solution
5279
for(int j=0; j<init.length; j++) {
53-
System.out.print(String.format("%s=%.5f",unknowns[j], init[j])+" ");
80+
System.out.print(String.format("%s=%.5f",unknowns[j], funArgs[j])+" ");
5481
}
5582
System.out.println();
5683
if(x.norm2() < eps)
5784
break;
5885
//Update initial guess
5986
for(int j=0; j<init.length; j++) {
60-
init[j] = init[j] - x.get(j, 0);
87+
funArgs[j] = funArgs[j] - x.get(j, 0);
6188
}
6289
}
6390
}
Collapse file

‎src/symjava/relational/Eq.java‎

Copy file name to clipboardExpand all lines: src/symjava/relational/Eq.java
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ public class Eq extends Relation {
1515
public Eq(Expr lhs, Expr rhs) {
1616
this.lhs = lhs;
1717
this.rhs = rhs;
18+
this.freeVars = new Expr[0];;
19+
this.params = new Expr[0];
1820
}
1921

2022
public Eq(Expr lhs, Expr rhs, Expr[] freeVars) {
2123
this.lhs = lhs;
2224
this.rhs = rhs;
25+
this.freeVars = freeVars;
26+
this.params = new Expr[0];
2327
//Find dependent variables
2428
List<Expr> list = Utils.extractSymbols(lhs, rhs);
2529
List<Expr> depList = new ArrayList<Expr>();
Collapse file

‎src/symjava/symbolic/Func.java‎

Copy file name to clipboardExpand all lines: src/symjava/symbolic/Func.java
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public boolean isAbstract() {
5555
}
5656

5757
public BytecodeFunc toBytecodeFunc() {
58+
return toBytecodeFunc(false, false);
59+
}
60+
61+
public BytecodeFunc toBytecodeFunc(boolean isWriteFile, boolean staticMethod) {
5862
try {
5963
if(this.expr instanceof SymReal<?>) {
6064
SymReal<?> r = (SymReal<?>)this.expr;
@@ -64,7 +68,7 @@ public BytecodeFunc toBytecodeFunc() {
6468
* Return an instance of BytecodeFunc generated by this Func without writing a class file to disk.
6569
*/
6670
FuncClassLoader fcl = new FuncClassLoader();
67-
return fcl.newInstance(BytecodeUtils.genClass(this, false));
71+
return fcl.newInstance(BytecodeUtils.genClass(this, isWriteFile, staticMethod));
6872
//return (BytecodeFunc)Class.forName("symjava.bytecode."+this.label).newInstance();
6973
} catch (Exception e) {
7074
e.printStackTrace();
Collapse file

‎src/symjava/symbolic/Integrate.java‎

Copy file name to clipboardExpand all lines: src/symjava/symbolic/Integrate.java
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public Expr diff(Expr expr) {
7575
if(domain instanceof Interval) {
7676
Interval I = (Interval)domain;
7777
Expr end = I.getEnd();
78-
Expr intSubs = integrand.subs(domain.getCoordVars()[0], expr);
78+
Expr intSubs = integrand.subs(domain.getCoordVars()[0], end);
7979
return intSubs.multiply(end.diff(expr));
8080
}
8181
return null;
Collapse file

‎src/symjava/symbolic/utils/BytecodeSupport.java‎

Copy file name to clipboardExpand all lines: src/symjava/symbolic/utils/BytecodeSupport.java
+39Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package symjava.symbolic.utils;
22

3+
import java.lang.reflect.Method;
4+
35
public class BytecodeSupport {
46
public static double powi(double base, int exp) {
57
if(exp == 0) return 1.0;
@@ -30,9 +32,46 @@ public static double log(double base, double expr) {
3032
return Math.log(expr)/Math.log(base);
3133
}
3234

35+
public static double numIntegrate1D(double begin, double end, double step, String className) {
36+
37+
Method method;
38+
try {
39+
method = BytecodeSupport.class.getClassLoader().
40+
loadClass("symjava.bytecode."+className).
41+
getMethod("apply", new Class[] {double[].class});
42+
double[] args = { 0 };
43+
double sum = 0.0;
44+
for(double i=begin; i<=end; i+=step) {
45+
args[0] = i;
46+
Double val = (Double)method.invoke(null, args);
47+
//Double val = test_pdf(args);
48+
sum += val*step;
49+
}
50+
return sum;
51+
} catch (Exception e) {
52+
e.printStackTrace();
53+
}
54+
// for (Method m : methods) {
55+
// if (methodName.equals(m.getName())) {
56+
// // for static methods we can use null as instance of class
57+
// m.invoke(null, new Object[] {args});
58+
// break;
59+
// }
60+
// }
61+
return 0.0;
62+
}
63+
64+
public static double test_pdf(double[] args) {
65+
double x = args[0];
66+
return Math.exp(-0.5*x*x);
67+
//return Math.exp(-0.5*x*x)/Math.sqrt(2*Math.PI);
68+
}
69+
3370
public static void main(String[] args) {
3471
System.out.println(powi(2,-3));
3572
System.out.println(powi(2,0));
3673
System.out.println(powi(2,3));
74+
75+
System.out.println(numIntegrate1D(-10,10,0.1,"integrand_ae3c65a143de42739270977b140b4fdf")/Math.sqrt(2*Math.PI));
3776
}
3877
}
Collapse file

‎src/symjava/symbolic/utils/BytecodeUtils.java‎

Copy file name to clipboardExpand all lines: src/symjava/symbolic/utils/BytecodeUtils.java
+20-10Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package symjava.symbolic.utils;
22

3-
import static com.sun.org.apache.bcel.internal.Constants.ACC_PUBLIC;
4-
import static com.sun.org.apache.bcel.internal.Constants.ACC_SUPER;
3+
import static com.sun.org.apache.bcel.internal.Constants.*;
54

65
import java.util.ArrayList;
76
import java.util.Arrays;
@@ -127,7 +126,7 @@ public int compare(Expr o1, Expr o2) {
127126
return rlt;
128127
}
129128

130-
public static ClassGen genClass(Func fun, boolean writeClassFile) {
129+
public static ClassGen genClass(Func fun, boolean writeClassFile, boolean staticMethod) {
131130
String packageName = "symjava.bytecode";
132131
String clsName = fun.getName();
133132
String fullClsName = packageName+"."+clsName;
@@ -137,7 +136,10 @@ public static ClassGen genClass(Func fun, boolean writeClassFile) {
137136
InstructionList il = new InstructionList();
138137
InstructionFactory factory = new InstructionFactory(cg);
139138

140-
MethodGen mg = new MethodGen(ACC_PUBLIC, // access flags
139+
short acc_flags = ACC_PUBLIC;
140+
if(staticMethod)
141+
acc_flags |= ACC_STATIC;
142+
MethodGen mg = new MethodGen(acc_flags, // access flags
141143
Type.DOUBLE, // return type
142144
new Type[] { // argument types
143145
new ArrayType(Type.DOUBLE, 1)
@@ -163,6 +165,8 @@ public static ClassGen genClass(Func fun, boolean writeClassFile) {
163165
System.out.println(
164166
String.format(">>>Using args: %s", Utils.joinLabels(fExprArgs, ","))
165167
);
168+
} else {
169+
fExprArgs = fun.args;
166170
}
167171
HashMap<Expr, Integer> argsMap = new HashMap<Expr, Integer>();
168172
for(int i=0; i<fExprArgs.length; i++) {
@@ -182,7 +186,10 @@ public static ClassGen genClass(Func fun, boolean writeClassFile) {
182186
if(argIdx == null) {
183187
throw new IllegalArgumentException(ins+" is not in the argument list of "+fun.getLabel());
184188
}
185-
il.append(new ALOAD(1));
189+
if(staticMethod)
190+
il.append(new ALOAD(0)); //for static method
191+
else
192+
il.append(new ALOAD(1));
186193
il.append(new PUSH(cp, argIdx));
187194
il.append(new DALOAD());
188195
} else if(ins instanceof SymReal<?>) {
@@ -255,12 +262,15 @@ public static ClassGen genClass(Func fun, boolean writeClassFile) {
255262
} else if(ins instanceof Infinity) {
256263
il.append(new PUSH(cp, Double.NaN));
257264
} else if(ins instanceof Integrate) {
258-
Func f = new Func("integrand"+java.util.UUID.randomUUID().toString().replaceAll("-", ""),((Integrate) ins).integrand);
259-
BytecodeFunc ff = f.toBytecodeFunc();
265+
Integrate INT = (Integrate)ins;
266+
Func f = new Func("integrand_"+java.util.UUID.randomUUID().toString().replaceAll("-", ""),INT.integrand);
267+
//System.out.println(f);
268+
f.toBytecodeFunc(true, true); //Load class, could be better method to load a class
260269
//http://stackoverflow.com/questions/19119702/injecting-code-in-an-existing-method-using-bcel/19219759#19219759
261-
il.append(new PUSH());
262-
il.append(factory.createInvoke("symjava.symbolic.utils.BytecodeSupport", "numIntegrate",
263-
Type.DOUBLE, new Type[] { Type.DOUBLE, Type.DOUBLE, Type.OBJECT }, Constants.INVOKESTATIC));
270+
il.append(new PUSH(cp, 0.001)); //step, could be provide by INT
271+
il.append(new PUSH(cp, f.getName()));
272+
il.append(factory.createInvoke("symjava.symbolic.utils.BytecodeSupport", "numIntegrate1D",
273+
Type.DOUBLE, new Type[] { Type.DOUBLE, Type.DOUBLE, Type.DOUBLE, Type.STRING }, Constants.INVOKESTATIC));
264274
} else {
265275
throw new RuntimeException(ins.getClass() + " is not allowed when generating bytecode function!");
266276
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.