I tried to check the funny calculation of
x = -80538738812075974
y = 80435758145817515
z = 12602123297335631
x**3+y**3+z**3=42
with GNU Octave.
I used the symbolic package and wrote:
>> x = vpa('-80538738812075974')
x = (sym) -80538738812075974.0000000000000
>> y = vpa('80435758145817515')
y = (sym) 80435758145817515.0000000000000
>> z = vpa('12602123297335631')
z = (sym) 12602123297335631.0000000000000
>> vpa(x**3+y**3+z**3)
ans = (sym) -23634890844440363008.0000000000
So the answer is not 42, even with digits(50). Using wxMaxima I get the right result:
x : -80538738812075974;
y : 80435758145817515;
z : 12602123297335631;
x**3+y**3+z**3;
42
so the numbers are ok. Is it possible to work with arbitrary precision in GNU Octave?
I really don't understand what was wrong, but it works obviously only if all steps are done in the right order (and sym instead of vpa):
setenv PYTHON d:/anaconda3w64/python
pkg load symbolic
syms x y z
x = sym('-80538738812075974')
y = sym('80435758145817515')
z = sym('12602123297335631')
x**3+y**3+z**3
x = (sym) -80538738812075974
y = (sym) 80435758145817515
z = (sym) 12602123297335631
ans = (sym) 42
So the problem is finally solved.
Related
I am reading "Numerical Methods for Engineers" by Chapra and Canale. In it, they've provided pseudocode for the implementation of Euler's method (for solving ordinary differential equations). Here is the pseucode:
Pseucode for implementing Euler's method
I tried implementing this code in GNU Octave, but depending on the input values, I am getting one of two errors:
The program doesn't give any output at all. I have to press 'Ctrl + C' in order to break execution.
The program gives this message:
error: 'ynew' undefined near line 5 column 21
error: called from
Integrator at line 5 column 9
main at line 18 column 7
I would be very grateful if you could get this program to work for me. I am actually an amateur in GNU Octave. Thank you.
Edit 1: Here is my code. For main.m:
%prompt user
y = input('Initial value of y:');
xi = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = input('Output interval:');
x = xi;
m = 0;
xpm = x;
ypm = y;
while(1)
xend = x + xout;
if xend > xf
xend = xf;
h = dx;
Integrator(x,y,h,xend);
m = m + 1;
xpm = x;
ypm = y;
if x >= xf
break;
endif
endif
end
For Integrator.m:
function Integrator(x,y,h,xend)
while(1)
if xend - x < h
h = xend - x;
Euler(x,y,h,ynew);
y = ynew;
if x >= xend
break;
endif
endif
end
endfunction
For Euler.m:
function Euler(x,y,h,ynew)
Derivs(x,y,dydx);
ynew = y + dydx * h;
x = x + h;
endfunction
For Derivs.m:
function Derivs(x,y,dydx)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Edit 2: I shoud mention that the differential equation which Chapra and Canale have given as an example is:
y'(x) = -2 * x^3 + 12 * x^2 - 20 * x + 8.5
That is why the 'Derivs.m' script shows dydx to be this particular polynomial.
Here is my final code. It has four different M-files:
main.m
%prompt the user
y = input('Initial value of y:');
x = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = dx;
%boring calculations
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end
%plot the final result
plot(xp,yp);
title('Solution using Euler Method');
ylabel('Dependent variable (y)');
xlabel('Independent variable (x)');
grid on;
Integrator.m
%This function takes in 4 inputs (x,y,h,xend) and returns 2 outputs [x,y]
function [x,y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x);
[x,y] = Euler(x,y,h);
end
endfunction
Euler.m
%This function takes in 3 inputs (x,y,h) and returns 2 outputs [x,ynew]
function [x,ynew] = Euler(x,y,h)
dydx = Derivs(x,y);
ynew = y + dydx * h;
x = x + h;
endfunction
Derivs.m
%This function takes in 2 inputs (x,y) and returns 1 output [dydx]
function [dydx] = Derivs(x,y)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Your functions should look like
function [x, y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x)
[x,y] = Euler(x,y,h);
end%while
end%function
as an example. Depending on what you want to do with the result, your main loop might need to collect all the results from the single steps. One variant for that is
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end%while
Given two vectors of candidates:
x = [1 3 5];
y = [1 2 3 4];
I want to find which candidates satisfy an equation or formula. This is what I want to do:
f = x + y - 6;
solve f;
And then, it spits out the solutions:
5 1
3 3
If it matters, I am actually using Octave, not MatLab because I don't have a Windows machine. I know that I can do this with a for loop:
for i=x
for j=y
if i+j-6==0
disp([i j]);
end
end
This is a trivial example. I am looking for a solution that will handle much larger examples.
Solving such equations per "brute force" is generally a bad idea but here you go:
x = [1 3 5];
y = [1 2 3 4];
## build grid (also works for n vars)
[xx, yy] = ndgrid (x, y);
## anonymous function
f = #(x,y) abs(x + y - 6) < 16*eps
## true?
t = f (xx, yy);
## build result
[xx(t) yy(t)]
I am new to Octave, so I am trying to make some simple examples work before moving onto more complex projects.
I am trying to resolve the ODE dy/dx = a*x+b, but without success. Here is the code:
%Funzione retta y = a*x + b. Ingressi: vettore valori t; coefficienti a,b
clear all;
%Inizializza argomenti
b = 1;
a = 1;
x = ones(1,20);
function y = retta(a, x, b) %Definisce funzione
y = ones(1,20);
y = a .* x .+ b;
endfunction
%Calcola retta
x = [-10:10];
a = 2;
b = 2;
r = retta(a, x, b)
c = b;
p1 = (a/2)*x.^2+b.*x+c %Sol. analitica di dy/dx = retta %
plot(x, r, x, p1);
% Risolve eq. differenziale dy/dx = retta %
y0 = b; x0 = 0;
p2 = lsode(#retta, y0, x)
And the output is:
retta3code
r =
-18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22
p1 =
Columns 1 through 18:
82 65 50 37 26 17 10 5 2 1 2 5 10 17 26 37 50 65
Columns 19 through 21:
82 101 122
error: 'b' undefined near line 9 column 16
error: called from:
error: retta at line 9, column 4
error: lsode: evaluation of user-supplied function failed
error: lsode: inconsistent sizes for state and derivative vectors
error: /home/fabio/octave_file/retta3code.m at line 21, column 4
So, the function retta works properly the first time, but it fails when used in lsode.
Why does that happen? What needs to be changed to make the code work?
Somehow you still miss some important parts of the story. To solve an ODE y'=f(y,x) you need to define a function
function ydot = f(y,x)
where ydot has the same dimensions as y, both have to be vectors, even f they are of dimension 1. x is a scalar. For some traditional reason, lsode (a FORTRAN code used in multiple solver packages) prefers the less used order (y,x), in most text books and other solvers you find the order (x,y).
Then to get solution samples ylist over sample points xlist you call
ylist = lsode("f", y0, xlist)
where xlist(1) is the initial time.
The internals of f are independent of the sample list list and what size it has. It is a separate issue that you can use multi-evaluation to compute the exact solution with something like
yexact = solexact(xlist)
To pass parameters, use anonymous functions, like in
function ydot = f(y,x,a,b)
ydot = [ a*x+b ]
end
a_val = ...
b_val = ...
lsode(#(y,x) f(y,x,a_val, b_val), y0, xlist)
The code as modified below works, but I'd prefer to be able to define the parameters a and b out of the function and then pass them to rdot as arguments.
x = [-10,10];
a = 1;
b = 0;
c = b;
p1 = (a/2).*(x.^2)+b.*x+c %Sol. analitica di dy/dx = retta %
function ydot = rdot(ydot, x)
a = 1;
b = 0;
ydot = ones(1,21);
ydot = a.*x .+ b;
endfunction
y0 = p1(1); x0 = 0;
p2 = lsode("rdot", y0, x, x0)'
plot(x, p1, "-k", x, p2, ".r");
How do I do below in Lua please?
I would like to get my variable returned to use it on another computation.
def xy(x, y):
z = x * y
return z
z = xy(2, 5)
z2 = z * 7
print (z2)
local function xy(x, y)
local z = x * y
return z
end
local z = xy(2, 5)
local z2 = z * 7
print(z2)
Remove the first local if you want the function xy to be global.
I have been trying to display the an and bn fourier coefficients in matlab but no success, I was able to display the a0 because that is not part of the iteration.
I will highly appreciate your help, below is my code
syms an;
syms n;
syms t;
y = sym(0);
L = 0.0005;
inc = 0.00001; % equally sample space of 100 points
an = int(3*t^2*cos(n*pi*t/L),t,-L,L)*(1/L);
bn = int(3*t^2*sin(n*pi*t/L),t,-L,L)*(1/L);
a0 = int(3*t^2,t,-L,L)*(1/L);
a0 = .5 *a0;
a0=a0
for i=1:5
y = subs(an, n, i)*cos(i*pi*t/0.0005)
z = subs(bn, n, i)*sin(i*pi*t/0.0005)
end
If everything you stated within your question is correct, I would tend to solve it this way:
clc, clear all,close all
L = 0.0005;
n = 5;
an = zeros(1,n);
bn = zeros(1,n);
for i = 1:5
f1 = #(t) 3.*(t.^2).*cos(i.*pi.*t./L);
f2 = #(t) 3.*(t.^2).*sin(i.*pi.*t./L);
an(i) = quad(f1,-L,L).*(1./L);
bn(i) = quad(f2,-L,L).*(1./L);
a0 = .5.*quad(#(t) 3.*t.^2,-L,L).*(1./L);
end
I hope this helps.