Skip to content

Commit

Permalink
modified: CeresHelper.js
Browse files Browse the repository at this point in the history
	modified:   dist/ceres.js
	modified:   docs/index.html
  • Loading branch information
miner committed Jan 20, 2024
1 parent 9a35b6b commit 02bc717
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 224 deletions.
117 changes: 7 additions & 110 deletions CeresHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ export class Ceres {
}

static sanitizeInput(mathExpression) {
if (mathExpression.indexOf('=') > -1)
{
let m_split = mathExpression.split("=")
mathExpression = m_split[0]+"-("+m_split[1]+")"
}

const validExpression = /^[0-9\s+\-/*()\[\]^sincoxetalaqrtPi.E]*$/;
const validStructure = /^[\d\s+\-/*()\[\]^]*$/;

Expand Down Expand Up @@ -201,116 +207,7 @@ export class Ceres {
let max_trust_region_radius = (isNumber(jsonSystem.max_trust_region_radius)) ? jsonSystem.max_trust_region_radius : 1e16;
let max_num_consecutive_invalid_steps = (isNumber(jsonSystem.max_num_consecutive_invalid_steps)) ? jsonSystem.max_num_consecutive_invalid_steps : 5;
const results = await this.solve(initial_guess, max_numb_iterations, parameter_tolerance, function_tolerance, gradient_tolerance, max_solver_time_in_seconds, initial_trust_region_radius, max_trust_region_radius, max_num_consecutive_invalid_steps);
results.report = jsonFunctions.map(i => 'Function: ' + i + ' = 0\n')+"\n\n"+results.report
results.report = jsonFunctions.map(i => 'Function: ' + i + ' = 0\n').join("\r\n")+"\n\n"+results.report
return results;
}
}

/*
class CeresGrad {
constructor() {
this.loaded = false
this.fxn = []
this.lowerbound = []
this.upperbound = []
this.callback = []
// Create example data to test float_multiply_array
this.varLength = 0
this.maxLength = 1000
this.data = new Float64Array(this.maxLength);
this.promise = new Promise(function(resolve, reject){
CeresModule().then(function(Module){
this.instance = new Module.CeresjsGrad
// Get data byte size, allocate memory on Emscripten heap, and get pointer
let nDataBytes = this.data.length * this.data.BYTES_PER_ELEMENT;
let dataPtr = Module._malloc(nDataBytes);
// Copy data to Emscripten heap (directly accessed from Module.HEAPU8)
this.dataHeap = new Float64Array(Module.HEAPF64.buffer, dataPtr, nDataBytes);
this.dataHeap.set(new Float64Array(this.data.buffer));
this.loaded = true
resolve()
}.bind(this))
}.bind(this))
}
// Method
add_function(fn) {
this.fxn.push(fn)
}
// Method
add_lowerbound(xNumber, lowerBound) {
this.lowerbound.push([xNumber, lowerBound])
}
// Method
add_upperbound(xNumber, upperBound) {
this.upperbound.push([xNumber, upperBound])
}
// Method
add_callback(fn) {
this.callback.push(fn)
}
reset(){
this.instance.reset();
this.fxn = []
this.lowerbound = []
this.upperbound = []
this.callback = []
}
//Method
load_fxns(){
for(let i = 0; i < this.fxn.length; i++){
let newfunc = function f(){
let x = new Float64Array(this.dataHeap.buffer, this.dataHeap.byteOffset, this.varLength);
return this.fxn[i](x)
}
this.instance.add_function(newfunc.bind(this));
}
for(let i = 0; i < this.lowerbound.length; i++){
this.instance.add_lowerbound(this.lowerbound[i][0], this.lowerbound[i][1]);
}
for(let i = 0; i < this.upperbound.length; i++){
this.instance.add_upperbound(this.upperbound[i][0], this.upperbound[i][1]);
}
for(let i = 0; i < this.callback.length; i++){
let newfunc = function f(evaluate_jacobians, new_evaluation_point){
let x = new Float64Array(this.dataHeap.buffer, this.dataHeap.byteOffset, this.varLength);
return this.callback[i](x, evaluate_jacobians, new_evaluation_point);
}
this.instance.add_callback(newfunc.bind(this));
}
}
// Method
solve(xi, max_numb_iterations = 2000, parameter_tolerance = 1e-10, function_tolerance = 1e-16, gradient_tolerance = 1e-16, max_solver_time_in_seconds = 100) {
if(this.loaded == true){
this.varLength = xi.length
this.load_fxns()
for(let i = 0; i < xi.length; i++){
this.dataHeap[i] = xi[i];
}
this.instance.setup_x(this.dataHeap.byteOffset, this.varLength);
let success = this.instance.solve(max_numb_iterations, parameter_tolerance, function_tolerance, gradient_tolerance, max_solver_time_in_seconds);
let report = this.instance.get_report();
let message = this.instance.get_message();
let x = new Float64Array(this.dataHeap.buffer, this.dataHeap.byteOffset, this.varLength)
let normalArray = [].slice.call(x);
let txt = "";
for(let i=0; i<normalArray.length; i++){
txt = txt + "\n" + "x" + i + " = " + normalArray[i]
}
return { success: success, message: message, x: normalArray, report: report+txt}
}
else{
console.log("Warning the Ceres.js wasm has not been loaded yet.")
}
}
remove(){
}
}
*/
117 changes: 7 additions & 110 deletions dist/ceres.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 111 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ <h2>Numerical Optimization Library in JavaScript</h2>
<a href="#about">About</a> |
<a href="#examples">Examples</a> |
<a href="#docs">Documentation</a> |
<a href="#contact">Contact</a>
<a href="#code_gen">Generate Code</a>
</nav>

<section id="intro" class="container">
Expand Down Expand Up @@ -271,9 +271,116 @@ <h4>Class: Ceres</h4>
</ul>
</section>

<section id="contact" class="container">
<h2>Contact</h2>
<!-- Contact Information / Form Here -->
<section id="code_gen" class="container">
<h2>Code Generator</h2>
<div id="forms">

<p>
<label for="eq1">1st Equation to Solve</label>
<math-field id="eq1">y=2 \cdot x^2-8 \cdot x-3</math-field>
</p>

<p>
<label for="eq2">2nd Equation to Solve</label>
<math-field id="eq2">y = x+2</math-field>
</p>

<p>
<label for="sym1">Letter representing first variable</label>
<math-field id="sym1">x</math-field> = <math-field id="res1">??</math-field>; Guess = <math-field id="guess1">4</math-field>
</p>

<p>
<label for="sym2">Letter representing first variable</label>
<math-field id="sym2">y</math-field> = <math-field id="res2">??</math-field>; Guess = <math-field id="guess2">1</math-field>
</p>
<script>
async function ceresSolve() {

let eq1 = document.getElementById("eq1").getValue("ascii-math");
let eq2 = document.getElementById("eq2").getValue("ascii-math");

let sym1 = document.getElementById("sym1").getValue("ascii-math");
let sym2 = document.getElementById("sym2").getValue("ascii-math");

let guess1 = document.getElementById("guess1").getValue("ascii-math");
let guess2 = document.getElementById("guess2").getValue("ascii-math");

let jsonSystem = {
"variables": {
[sym1]: {
"guess": guess1,
},
[sym2]: {
"guess": guess2,
},
},
"functions": [
eq1,
eq2
],
}

const {Ceres} = await import('https://cdn.jsdelivr.net/gh/Pterodactylus/Ceres.js@latest/dist/ceres.min.js');
let solver = new Ceres()
let results = await solver.run(jsonSystem);
document.getElementById("generator_demo").value = results.report
console.log(results.x)
document.getElementById("res1").setValue(results.x[0].toFixed(10))
document.getElementById("res2").setValue(results.x[1].toFixed(10))
}
</script>

<script>
function gen_source_code() {

let eq1 = document.getElementById("eq1").getValue("ascii-math");
let eq2 = document.getElementById("eq2").getValue("ascii-math");

let sym1 = document.getElementById("sym1").getValue("ascii-math");
let sym2 = document.getElementById("sym2").getValue("ascii-math");

let guess1 = document.getElementById("guess1").getValue("ascii-math");
let guess2 = document.getElementById("guess2").getValue("ascii-math");

document.getElementById("generated_code").innerHTML = `
async function ceresSolve(jsonSystem) {
const {Ceres} = await import('https://cdn.jsdelivr.net/gh/Pterodactylus/Ceres.js@latest/dist/ceres.min.js');
let solver = new Ceres()
let results = await solver.run(jsonSystem);
console.log(results.x) //Print solver results
console.log(results.report) //Print solver report
}
let jsonSystem = {
"variables": {
"${sym1}": {
"guess": ${guess1},
},
"${sym2}": {
"guess": ${guess2},
},
},
"functions": [
"${eq1}",
"${eq2}"
],
}
ceresSolve(jsonSystem) //Call the function
`
Prism.highlightAll();
}
</script>

<button id="solve" onclick="gen_source_code(); ceresSolve()">Generate Code</button>
<textarea id="generator_demo" rows="10" cols="110"></textarea>
<pre><code id="generated_code" class="language-js"></code></pre>


</div>

<script src="https://unpkg.com/mathlive/dist/mathlive.min.js"></script>
</section>

<footer>
Expand Down

0 comments on commit 02bc717

Please sign in to comment.