Skip to content

Forward Euler in JavaScript #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Oct 27, 2018
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
31 changes: 31 additions & 0 deletions contents/forward_euler_method/code/javascript/euler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
function forwardEuler(time_step, n) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was already said about snake_case vs. camelCase also applies to variables. This should be timeStep. The same goes for is_approx, euler_result and check_result further down.

const arr = [1];
for (let i = 1; i <= n; i++) {
arr[i] = arr[i - 1] - 3 * arr[i - 1] * time_step;
}
return arr;
}

function checkEuler(arr, time_step, threshold) {
const is_approx = true;
arr.forEach(function callback(value, i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll go from the point where this thread ended.

I am not sure about the => part. What is its purpose? I did not see it in the docs.

The arrow (=>) is part of the arrow function syntax. It's an alternative way to create an anonymous function. But it's not just another syntax, it actually behaves differently than function () {}. If you want to read up on the differences, you now know what to search for (arrow function). I will not go into detail here. All I will say is that you should probably get in the habit of using them. They're really quite common these days.

This is how an arrow function with a full function body would look:

const func1 = (param1, param2) => {
  // Function body goes here
};

If a function only has one line in it, which is a return statement, you can omit the { } around the function body, so these 2 are the same:

const func1 = (param1, param2) => {
  return param1 + param2;
};

const func2 = (param1, param2) => param1 + param2;

I know what you're thinking. This looks kind of weird and unreadable. But trust me, it's just a syntax that you're not used to and once you're used to seeing it, it will look completely normal and you'll be able to quickly understand its meaning.

If an arrow function has only one parameter, you can also omit the ( ) around the parameter list. So these 2 would be the same:

const double1 = (num) => num * 2;
const double2 = num => num * 2;

To give you a practical example of why you would use these forms of arrow functions, here is a snippet of code that takes an array with numbers and creates a second array where all the numbers are doubled:

const doubleArr = arr.map(num => num * 2);

And finally, this is how you could use an arrow function in your code:

arr.forEach((_value, i) => {
  // Function body goes here
});

Also note how I called the first parameter _value with an underscore. That is because it's unused and by convention, you denote an unused parameter by giving it a _ prefix or simply naming it _. Some editors like VSCode will mark an unused parameter as unused unless you prefix it with an underscore.

Copy link
Contributor Author

@depate depate Oct 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok,

I think I got it at least for the first part. This short syntax for functions is easy, because you declare a variables value to the result of a function one evokes with a set of parameters like:

const doubleArr = arr.map(num => num * 2);

But using the same syntax just to define a function on to parameters without a result being assigned to a variable outside of it.

Intuitively I would write it somehow that inside the checkEuler function the const isApprox gets the value of the check directly.

Something like:

const isApprox = arr.forEach(( _value, i) => {
  [...] // here is the calculation of the solution variable A which gets compared later on with threshold B
  if ( A > B) {
    [...] 
    return  (A > B) // returning the logical value of the check here, but I can't tell if this valid
  }
});

If this would somehow be possible, then we are saving at least one line of code there. Because const isApprox does not need to be initialised before as true.

Edit:

I see a problem with this procedure: If A > B is never true, which is the intended behavior, then const isApprox will never get a boolean value. So an else statement must be defined which produces more lines of code than the previous implementation.

I felt smart for a little moment in time.

const solution = Math.exp(-3 * time_step * i);

if (Math.abs(arr[i] - solution) > threshold) {
console.log(arr[i], solution);
is_approx = false;
}
});
return is_approx;
}

function main() {
const time_step = 0.01;
const threshold = 0.01;
const n = 100;
var euler_result = forwardEuler(time_step, n);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed var to let and const in most places, but not here. Let me get this straight: There is no good reason to use var. Why?

  1. On the top level of a function, var and let do exactly the same.
  2. In a block inside of a function, var does something kind of weird while let actually does what you would expect. So let is actually better to use.
function foo() {
  // <- This is where JavaScript moves the var declaration
  if (true) {
    var bar; // JavaScript moves this declaration to the top of the function and outside of the block
    let baz;
  }
}

So in case 1 let and var are the same and in case 2 let is objectively better. So why use var in the first place? I hope you can see how there's no need for it in modern code now. =)

var check_result = checkEuler(euler_result, time_step, threshold);
console.log(check_result);
}

main();
2 changes: 2 additions & 0 deletions contents/forward_euler_method/forward_euler_method.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ Full code for the visualization follows:
[import, lang:"matlab"](code/matlab/euler.m)
{% sample lang="swift" %}
[import, lang:"swift"](code/swift/euler.swift)
{% sample lang="js" %}
[import, lang:"javascript"](code/javascript/euler.js)
{% endmethod %}

<script>
Expand Down