Write Euler's method in Mathematica - math

I would like to write a function that has a loop in it which preforms the operations necessary for Euler's method. Below it my poor attempt.
In[15]:= Euler[icx_,icy_,h_,b_,diffeq_] :=
curx;
cury;
n=0;
curx = icx;
cury = icy;
While
[curx != b,
Print["" + n + " | " + curx + cury];
n++;
dq = StringReplace[diffeq, "y[x]" -> curx];
dq = StringReplace[dq, "x" -> cury];
curx+=h;
cury=cury+h*dq;
]
In[21]:= Euler[0, 0, .1, 1, e^-y[x]]
Out[21]= icx

To solve an ODE by Euler's method in Mathematica the code is:
Clear["Global`*"];
s = NDSolve[{y'[x] == Exp[-y[x]], y[0] == 0}, y, {x, 0, 1},
Method -> {"FixedStep", Method -> "ExplicitEuler"},
MaxSteps -> 20000];
Plot[Evaluate[y[x] /. s], {x, 0, 1}, PlotRange -> Full]
Otherwise, if you are dealing with homework, please state that on your tags.
HTH!

Here is an example of solution without any explicit loop.
If a loop is needed, I let you do it yourself.
EulerODE[f_ /; Head[f] == Function, {t0_, y0_}, t1_, n_] :=
Module[{h = (t1 - t0)/n // N, tt, yy},
tt[0] = t0; yy[0] = y0;
tt[k_ /; 0 < k < n] := tt[k] = tt[k - 1] + h;
yy[k_ /; 0 < k < n] :=
yy[k] = yy[k - 1] + h f[tt[k - 1], yy[k - 1]];
Table[{tt[k], yy[k]}, {k, 0, n - 1}]
];
ty = EulerODE[Function[{t, y}, y/t + y^2/t^2], {1, 1}, 2, 100] ;
Plot[Interpolation[ty][t], {t, 1, 2}]

Related

How can I conveniently convert a 2-dimensional array into a 2-dimensional vector?

I'm following the Rust-wasm tutorial and I want to be able to easily add a ship (a shape really) to the Universe in the game of life.
As a first step, I'd like to convert a 2-dimensional array of 0 or 1 representing a shape into a vector of indices representing the coordinates of the shape in the Universe.
I have a working piece of code but I'd like to make it a bit more user-friendly:
const WIDTH: u32 = 64;
const HEIGHT: u32 = 64;
/// glider: [[0, 1, 0], [0, 0, 1], [1, 1, 1]]
fn make_ship(shape: Vec<Vec<u32>>) -> Vec<u32> {
let mut ship: Vec<u32> = Vec::new();
for row_idx in 0..shape.len() {
for col_idx in 0..shape[row_idx].len() {
let cell = shape[row_idx][col_idx];
if cell == 1 {
ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
}
}
}
ship
}
#[test]
fn glider() {
let glider = vec![vec![0, 1, 0], vec![0, 0, 1], vec![1, 1, 1]];
println!("{:?}", make_ship(glider));
}
The test shows my problem: the verbosity of vec!s. Ideally I'd like to be able to write it without all the vec!. The code of make_ship shouldn't care about the size of the shape arrays. Ideal example:
let glider = [[0, 1, 0],
[0, 0, 1],
[1, 1, 1],];
The question is: how to express a shape nicely with simple arrays and have the function make_ship take 2-dimensional vectors of arbitrary size?
Reducing the number of vec!s is possible with a custom macro:
#[macro_export]
macro_rules! vec2d {
($($i:expr),+) => { // handle numbers
{
let mut ret = Vec::new();
$(ret.push($i);)*
ret
}
};
([$($arr:tt),+]) => { // handle sets
{
let mut ret = Vec::new();
$(ret.push(vec!($arr));)*
ret
}
};
}
fn main() {
let glider = vec2d![[0, 1, 0],
[0, 0, 1],
[1, 1, 1]];
let glider2 = vec2d![[0, 1, 0, 1],
[0, 0, 1, 0],
[1, 1, 1, 0],
[0, 1, 1, 0]];
println!("{:?}", glider); // [[0, 1, 0], [0, 0, 1], [1, 1, 1]]
println!("{:?}", glider2); // [[0, 1, 0, 1], [0, 0, 1, 0], [1, 1, 1, 0], [0, 1, 1, 0]]
}
Your initial function could also use a bit of an improvement with the help of Rust's iterators:
fn make_ship(shape: Vec<Vec<u32>>) -> Vec<u32> {
shape
.iter()
.enumerate()
.flat_map(|(row, v)| {
v.iter().enumerate().filter_map(move |(col, x)| {
if *x == 1 {
Some(col as u32 + row as u32 * WIDTH)
} else {
None
}
})
})
.collect()
}
Vec<Vec<_>> is actually not a 2-dimensional vector but a "vector of vectors". This has major implications (assuming the outer vector is interpreted as rows, and the inner as columns):
Rows can have different lengths. That is often not what you would want.
Rows are individual objects, potentially scattered all over the heap memory.
In order to access an element you have to follow two indirections.
I would implement a 2-dimensional vector rather as a 1-dimensional vector with additional information regarding its dimensions. Something like:
struct Vec2D<T> {
n_rows: usize, // number of rows
n_cols: usize, // number of columns (redundant, since we know the length of data)
data: Vec<T>, // data stored in a contiguous 1D array
}
This struct can be initialized with
let glider = Vec2D {
n_rows: 3,
n_cols: 3,
data: vec![0, 1, 0,
0, 0, 1,
1, 1, 1],
};
Or more conveniently with functions or macros that take arrays-of-arrays. (See #ljedrz's answer for inspiration).
To access an element in the struct you'd have to use a little bit of math to convert a 2D index into a 1D index:
impl<T> Vec2D<T> {
fn get(&self, row: usize, col: usize) -> &T {
assert!(row < self.n_rows);
assert!(col < self.n_cols);
&self.data[row * self.n_cols + col]
}
}
While implementing your own 2-dimensional array type is a fun exercise, for productive use it may be more efficient to use an existing solution such as the ndarray crate.
Another solution is to transparently handle Vec<T> and [T] using AsRef:
fn make_ship<T>(shape: &[T]) -> Vec<u32>
where
T: AsRef<[u32]>,
{
let mut ship: Vec<u32> = Vec::new();
for row_idx in 0..shape.len() {
let row = shape[row_idx].as_ref();
for col_idx in 0..row.len() {
let cell = row[col_idx];
if cell == 1 {
ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
}
}
}
ship
}
This handles the following:
let glider = vec![vec![0, 1, 0], vec![0, 0, 1], vec![1, 1, 1]];
let glider = [[0, 1, 0], [0, 0, 1], [1, 1, 1]];
let glider = [vec![0, 1, 0], vec![0, 0, 1], vec![1, 1, 1]];
let glider = vec![[0, 1, 0], [0, 0, 1], [1, 1, 1]];
An even better solution is to not care about slices/vectors at all, and use iterators:
fn make_ship<'a, T, U>(shape: &'a T) -> Vec<u32>
where
&'a T: std::iter::IntoIterator<Item = U>,
U: std::iter::IntoIterator<Item = &'a u32>,
{
let mut ship: Vec<u32> = Vec::new();
for (row_idx, row) in shape.into_iter().enumerate() {
for (col_idx, &cell) in row.into_iter().enumerate() {
if cell == 1 {
ship.push(col_idx as u32 + row_idx as u32 * WIDTH);
}
}
}
ship
}
Which also handle the cases above, but could also handle a type such as #kazemakase's Vec2D if it provided such iterators.

canberra distance - inconsistent results

I'm trying to understand what's going on with my calculation of canberra distance. I write my own simple canberra.distance function, however the results are not consistent with dist function. I added option na.rm = T to my function, to be able calculate the sum when there is zero denominator. From ?dist I understand that they use similar approach: Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing.
canberra.distance <- function(a, b){
sum( (abs(a - b)) / (abs(a) + abs(b)), na.rm = T )
}
a <- c(0, 1, 0, 0, 1)
b <- c(1, 0, 1, 0, 1)
canberra.distance(a, b)
> 3
# the result that I expected
dist(rbind(a, b), method = "canberra")
> 3.75
a <- c(0, 1, 0, 0)
b <- c(1, 0, 1, 0)
canberra.distance(a, b)
> 3
# the result that I expected
dist(rbind(a, b), method = "canberra")
> 4
a <- c(0, 1, 0)
b <- c(1, 0, 1)
canberra.distance(a, b)
> 3
dist(rbind(a, b), method = "canberra")
> 3
# now the results are the same
Pairs 0-0 and 1-1 seem to be problematic. In the first case (0-0) both numerator and denominator are equal to zero and this pair should be omitted. In the second case (1-1) numerator is 0 but denominator is not and the term is then also 0 and the sum should not change.
What am I missing here?
EDIT:
To be in line with R definition, function canberra.distance can be modified as follows:
canberra.distance <- function(a, b){
sum( abs(a - b) / abs(a + b), na.rm = T )
}
However, the results are the same as before.
This might shed some light on the difference. As far as I can see this is the actual code being run for computing the distance
static double R_canberra(double *x, int nr, int nc, int i1, int i2)
{
double dev, dist, sum, diff;
int count, j;
count = 0;
dist = 0;
for(j = 0 ; j < nc ; j++) {
if(both_non_NA(x[i1], x[i2])) {
sum = fabs(x[i1] + x[i2]);
diff = fabs(x[i1] - x[i2]);
if (sum > DBL_MIN || diff > DBL_MIN) {
dev = diff/sum;
if(!ISNAN(dev) ||
(!R_FINITE(diff) && diff == sum &&
/* use Inf = lim x -> oo */ (int) (dev = 1.))) {
dist += dev;
count++;
}
}
}
i1 += nr;
i2 += nr;
}
if(count == 0) return NA_REAL;
if(count != nc) dist /= ((double)count/nc);
return dist;
}
I think the culprit is this line
if(!ISNAN(dev) ||
(!R_FINITE(diff) && diff == sum &&
/* use Inf = lim x -> oo */ (int) (dev = 1.)))
which handles a special case and may not be documented.

F# adding polynomials recursively

I'm trying to write a function in F# that adds polynomials recursively. My polynomials can be represented as a list of tuples.
For example, 2x^4 + 3x^2 + x + 5 is equal to [(2.0,4);(3.0,2);(1.0,1);(5.0,0)]
All polynomials are properly structured (no repeated terms with the same degree, no terms with zero coefficients unless it is the zero polynomial, terms sorted by decreasing exponent no empty input list).
I'm having trouble doing this. Here is my code
type term = float * int
type poly = term list
let rec atp(t:term,p:poly):poly =
match p with
| [] -> []
| (a, b) :: tail -> if snd t = b then (fst t + a, b) :: [] elif snd t > b then t :: [] else ([]) :: atp(t, tail)
(* val atp : t:term * p:poly -> poly *)
let rec addpolys(p1:poly,p2:poly):poly =
match p1 with
| [] -> []
| (a,b) :: tail -> atp((a,b), p2) # addpolys(tail, p2)
I have two polynomials
val p2 : poly = [(4.5, 7); (3.0, 4); (10.5, 3); (2.25, 2)]
val p1 : poly = [(3.0, 5); (2.0, 2); (7.0, 1); (1.5, 0)]
and when I call the function, my result is
val p4 : poly =
[(4.5, 7); (3.0, 5); (3.0, 4); (3.0, 5); (10.5, 3); (3.0, 5); (4.25, 2)]
When the correct answer is
[(4.5, 7); (3.0, 5); (3.0, 4); (10.5, 3); (4.25, 2); (7.0, 1); (1.5, 0)]
Unfortunately your code does not compile therefore it is difficult for me to understand your intentions. But I've got an own implementation for your problem. Maybe it will help you:
// addpoly: (float * 'a) list -> (float * 'a) list -> (float * 'a) list
let rec addpoly p1 p2 =
match (p1, p2) with
| [], p2 -> p2
| p1, [] -> p1
| (a1, n1)::p1s, (a2, n2)::p2s ->
if n1 < n2 then (a2, n2) :: addpoly p1 p2s
elif n1 > n2 then (a1, n1) :: addpoly p1s p2
else (a1+a2, n1) :: addpoly p1s p2s
let p1 = [(3.0, 5); (2.0, 2); ( 7.0, 1); (1.5, 0)]
let p2 = [(4.5, 7); (3.0, 4); (10.5, 3); (2.25, 2)]
let q = addpoly p1 p2
// val q : (float * int) list =
// [(4.5, 7); (3.0, 5); (3.0, 4); (10.5, 3); (4.25, 2); (7.0, 1); (1.5, 0)]
I would like to make a little note. When you change the representation of the
polynomials a little bit then you can simplify the implementation of your function. You can express a polynomial as a list of its coefficients.
For example when you have this polynomial
p1 = 5.0x^5 + 2.0x^2 + 7.0x
you can write it also like this
p1 = 1.5x^0 + 7.0x^1 + 2.0x^2 + 0.0x^3 + 0.0x^4 + 5.0x^5
Therefore you are able to define the polynomial with this list:
let p1 = [1.5; 7.0; 2.0; 0.0; 0.0; 5.0]
Here are two functions which operates on the representation. polyval calculates the result for a given value and polyadd adds two polynomials. There implementation are rather simple:
// p1 = 1.5x^0 + 7.0x^1 + 2.0x^2 + 0.0x^3 + 0.0x^4 + 5.0x^5
let p1 = [1.5; 7.0; 2.0; 0.0; 0.0; 5.0]
// p2 = 0.0x^0 + 0.0x^1 + 2.25x^2 + 10.5x^3 + 3.0x^4 + 0.0x^5 + 0.0x^6 + 4.5x^7
let p2 = [0.0; 0.0; 2.25; 10.5; 3.0; 0.0; 0.0; 4.5]
// polyval: float list -> float -> float
let rec polyval ps x =
match ps with
| [] -> 0.0
| p::ps -> p + x * (polyval ps x)
// polyadd: float int -> float int -> float int
let rec polyadd ps qs =
match (ps, qs) with
| [], ys -> ys
| xs, [] -> xs
| x::xs, y::ys -> (x+y)::polyadd xs ys
let v = polyval p1 2.3
// val v : float = 349.99715
let p = polyadd p1 p2
// val p : float list = [1.5; 7.0; 4.25; 10.5; 3.0; 5.0; 0.0; 4.5]
Here's a completely generic, tail-recursive implementation:
let inline addPolys xs ys =
let rec imp acc = function
| (coeffx, degx)::xt, (coeffy, degy)::yt when degx = degy ->
imp ((coeffx + coeffy, degx)::acc) (xt, yt)
| (coeffx, degx)::xt, (coeffy, degy)::yt when degx > degy ->
imp ((coeffx, degx)::acc) (xt, (coeffy, degy)::yt)
| xs, yh::yt -> imp (yh::acc) (xs, yt)
| xh::xt, [] -> imp (xh::acc) (xt, [])
| [], yh::yt -> imp (yh::acc) ([], yt)
| [], [] -> acc
imp [] (xs, ys) |> List.rev
It has the type:
xs:( ^a * 'b) list -> ys:( ^a * 'b) list -> ( ^a * 'b) list
when ^a : (static member ( + ) : ^a * ^a -> ^a) and 'b : comparison
Since float has the member +, and int supports comparison, the type float * int matches these generic constraints:
> addPolys p1 p2;;
val it : (float * int) list =
[(4.5, 7); (3.0, 5); (3.0, 4); (10.5, 3); (4.25, 2); (7.0, 1); (1.5, 0)]

Wrong result in a PARI-implementation

I tried to implement an algorithm to calculate power towers
modulo m. Below the procedure tower should calculate
2^3^...^14^15 (mod m) and tower2 should calculate
15^14^...^3^2 (mod m). But for m = 163 , tower2
produces a wrong answer. I found out that a immediate
result is 0 and the procedure does not get this.
Can anyone fix the error ?
The procedure powmod is implemented and works perfectly :
powmod(basis,exponent,modul)={if(exponent==0,hilf=1);if(exponent>0,bin=binary(exponent);hilf=basis;hilf=hilf-truncate(hilf/modul)*modul;for(stelle=2,length(bin),hilf=hilf^2;if(bin[stelle]==1,hilf=hilf*basis);hilf=hilf-truncate(hilf/modul)*modul));hilf}
? tower
%19 = (p,q,r)->if(q==0,hilf=1);if(q==1,hilf=p);if(q==2,hilf=powmod(p,p,r));if(q>
2,x=[];for(j=1,q,x=concat(x,r);r=eulerphi(r));hilf=14^15;forstep(j=13,2,-1,r=x[j
-1];if(r>=2,hilf=powmod(j,hilf,r);w=factorint(r);w=component(w,2);while(hilf<vec
max(w),hilf=hilf+r))));component(Mod(hilf,r),2)
? tower2
%20 = (p,q,r)->if(q==0,hilf=1);if(q==1,hilf=p);if(q==2,hilf=powmod(p,p,r));if(q>
2,x=[];for(j=1,q,x=concat(x,r);r=eulerphi(r));hilf=3^2;forstep(j=13,2,-1,r=x[j-1
];if(r>=2,hilf=powmod(17-j,hilf,r);w=factorint(r);w=component(w,2);while(hilf<ve
cmax(w),hilf=hilf+r))));component(Mod(hilf,r),2)
?
The reason your code doesn't work is that you (recursively) compute x^n (mod r) as x^(n mod phi(r)) and this isn't true unless gcd(x,r) = 1.
Also, you don't need powmod since Mod(basis,modul)^expo is built-in.
Here's a general possibility :
\\ x[1]^(x[2]^( ...^ x[#x])) mod m, assuming x[i] > 1 for all i
tower(x, m) =
{ my(f = factor(m), P = f[,1], E = f[,2]);
chinese(vector(#P, i, towerp(x, P[i], E[i])));
}
towerp(x, p, e) =
{ my(q = p^e, i, t, v);
if (#x == 0, return (Mod(1, q)));
if (#x == 1, return (Mod(x[1], q)));
if (v = valuation(x[1], p),
t = x[#x]; i = #x;
while (i > 1,
if (t >= e, return (Mod(0, q)));
t = x[i]^t; i--);
if (t * v >= e, return (Mod(0, q)));
return (Mod(x[1], q)^t);
);
Mod(x[1], q)^lift(tower(x[2..#x], (p-1)*p^e));
}
? tower([2..15], 163)
%1 = Mod(162, 163)
? tower(Vecrev([2..15]), 163)
%2 = Mod(16, 163)

Is there an algorithm known for power towers modulo a number managing all cases?

I would like to have an implementation in PARI/GP
for the calculation of
a_1 ^ a_2 ^ ... ^ a_n (mod m)
which manages all cases, especially the cases where high powers appear in the phi-chain.
Does anyone know such an implementation ?
Here's a possibility using Chinese remainders to make sure the modulus is a prime power. This simplifies the computation of x^n mod m in the painful case where gcd(x,m) is not 1. The code assumes the a_i are > 1; most of the code checks whether p^a_1^a_2^...^a_n is 0 mod (p^e) for a prime number p, while avoiding overflow.
\\ x[1]^x[2]^ ...^ x[#x] mod m, assuming x[i] > 1 for all i
tower(x, m) =
{ my(f = factor(m), P = f[,1], E = f[,2]);
chinese(vector(#P, i, towerp(x, P[i], E[i])));
}
towerp(x, p, e) =
{ my(q = p^e, i, t, v);
if (#x == 0, return (Mod(1, q)));
if (#x == 1, return (Mod(x[1], q)));
if (v = valuation(x[1], p),
t = x[#x]; i = #x;
while (i > 1,
if (t >= e, return (Mod(0, q)));
t = x[i]^t; i--);
if (t * v >= e, return (Mod(0, q)));
return (Mod(x[1], q)^t);
);
Mod(x[1], q)^lift(tower(x[^1], (p-1)*p^e));
}
For instance
? 5^(4^(3^2)) % 163 \\ direct computation, wouldn't scale
%1 = 158
? tower([5,4,3,2], 163)
%2 = Mod(158, 163)

Resources