Octave solve multiple ODE systems - octave

I know I can use Octave built-in ODE solver to solve a ODE system. Now I want to solve the multiple ODE systems of the same structure but with different coefficients. For example, I have the following ODEs:
function xdot=f(x,t)
a = 0.1;
xdot(1) = a * x(1) ^ 2 + x(2);
xdot(2) = x(1) - x(2);
endfunction
Initial conditions x(1)=0, x(2)=0 at t=0. I want to get x(1) and x(2) at point t=1. I know I can solve this easily by using lsode command.
Now I want to change the value "a" from 0.1 to 20 with step 0.1, that is a=[0.1:0.1:20]. So I can get x(1) and x(2) from different "a". How do I do this in a loop? Do I need a global variable "a"?

I can't say I've ever used lsode before, but when I've had a variable in a function that I've wanted to change, I've had to declare it a global variable and then redefine the function. Something like
%doesn't work
f = #(x) a*x+2
for a= 0.1:0.1:20
f(1)
end
%does work
for a= 0.1:0.1:20
f = #(x) a*x+2 %your function here
%I usually end up using arrayfun() here in my applications, maybe lsode would work?
end
I'm no Octave expert, but this has worked for me, so maybe it'll work for you too.

Related

Can I define a maxima function f(x) which assigns to the argument x

Sorry for the basic question, but it's quite hard to find too much discussion on Maxima specifics.
I'm trying to learn some Maxima and wanted to use something like
x:2
x+=2
which as far as I can tell doesn't exist in Maxima. Then I discovered that I can define my own operators as infix operators, so I tried doing
infix("+=");
"+=" (a,b):= a:(a+b);
However this doesn't work, as if I first set x:1 then try calling x+=2, the function returns 3, but if I check the value of x I see it hasn't changed.
Is there a way to achieve what I was trying to do in Maxima? Could anyone explain why the definition I gave fails?
Thanks!
The problem with your implementation is that there is too much and too little evaluation -- the += function doesn't see the symbol x so it doesn't know to what variable to assign the result, and the left-hand side of an assignment isn't evaluated, so += thinks it is assigning to a, not x.
Here's one way to get the right amount of evaluation. ::= defines a macro, which is just a function which quotes its arguments, and for which the return value is evaluated again. buildq is a substitution function which quotes the expression into which you are substituting. So the combination of ::= and buildq here is to construct the x: x + 2 expression and then evaluate it.
(%i1) infix ("+=") $
(%i2) "+="(a, b) ::= buildq ([a, b], a: a + b) $
(%i3) x: 100 $
(%i4) macroexpand (x += 1);
(%o4) x : x + 1
(%i5) x += 1;
(%o5) 101
(%i6) x;
(%o6) 101
(%i7) x += 1;
(%o7) 102
(%i8) x;
(%o8) 102
So it is certainly possible to do so, if you want to do that. But may I suggest maybe you don't need it? Modifying a variable makes it harder to keep track, mentally, what is going on. A programming policy such as one-time assignment can make it easier for the programmer to understand the program. This is part of a general approach called functional programming; perhaps you can take a look at that. Maxima has various features which make it possible to use functional programming, although you are not required to use them.

error: 'y' undefined near line 8 column 12 error: called from computeCost at line 8 column 3

error: 'y' undefined near line 8 column 12
error: called from computeCost at line 8 column 3
Here is my code:
1;
function J = computeCost(X, y, theta)
%COMPUTECOST Compute cost for linear regression
% J = COMPUTECOST(X, y, theta) computes the cost of using theta as the
% parameter for linear regression to fit the data points in X and y
% Initialize some useful values
m = length(y); % number of training examples
% You need to return the following variables correctly
J = 0;
% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
% You should set J to the cost.
J = sum(( X * theta - y ) .^2 )/( 2 * m );
% =========================================================================
end
I am guessing it's an error from Coursera ML course assignment. I think you are trying to run the file which contains the implementation of function computeCost(X, y, theta), not the file which calls the computeCost(,,) function with values of X, y, theta. This is why you are getting the error as you aren't providing y.
Run the file which is calling computeCost() function, not the file which contains the implementation of computeCost() function.
That is:
For Week2 Assignment 1: Run ex1.m file
For Week3 Assignment 2: Run ex2.m file
There are two things happening here. First you are defining your function dynamically as opposed to in its own file; not sure why you would prefer that.
Second, after having defined this computeCost function, you are calling it from a context where you did not pass a y argument (or presumably, you didn't pass any arguments to it, and y happens to be the first one detected as missing inside the function).
Since this is a cost function and your code looks suspiciously like code from Andrew Ng's Machine Learning course on Coursera, I am going to go out on a limb here and guess that you called computeCost from something else that was supposed to use it as a cost function to be optimised, e.g. fminunc. Typically functions like fminunc expect a function handle as an argument, but they expect a very specific function handle too. If you look at the help of fminunc, it states that:
FCN should accept a vector (array) defining the unknown variables,
and return the objective function value, optionally with gradient.
Therefore, if you want to pass a function that is to be computed with three arguments, you need to "wrap" it into your own handle, which you can define on the spot, e.g. #(x) computeCost(x, y, t) (assuming 'y' and 't' exist already).
So, I'm guessing that instead of calling fminunc like so: fminunc( #(x) computeCost(x, y, t),
you probably called it like so: fminunc( #computeCost )
or even like so: fminunc( computeCost ) (which evaluates the function first, rather than pass a function handle as an argument).
Basically, go back to the code given to you by coursera, or read the notes carefully. You're calling things the wrong way.
Actually, you are trying to run a function and you can't run it until you provide the desired no. of parameters. Doing so, you may encounter the following error:
computeCost error: 'y' undefined near line 7 column 12
error: called from computeCost at line 7 column 3
As you see, here I'm calling this function without passing any argument.
SOLUTION:
You can test your code by running 'ex1' script. After that submit your work by calling 'submit' script.

How to solve a function between a range (0,2) with different steps for x and y in Fortran without arrays?

Basically, I need to solve a function, ill use x^2 * y^3 for an example, but using the x and y values over a range of (0,2), with different steps for x values and for y values. For example, if the step was 1 for both x and y, I would just solve the function for (0,0),(0,2),(2,0), and (2,2).
I'm not sure how to accomplish this in Fortran without using arrays. I was thinking about using a "DO" and then solving the function for all of the initial "y" values, while using the correct amount of steps for "x," but im not sure how I would get the second "y" value with the "x" values reset so that the "y" can be calculated with all of the x values.
Thank you!
Here is a simple solution, based on do concurrent construct in modern Fortran (>2008) which is guaranteed to be equally or more efficient than the conventional do-loops in Fortran:
program hello
integer :: x,y
real :: stepSizeX = 0.1, stepSizeY = 0.2
do concurrent(x=0:2:1,y=0:2:1)
write(*,*) (stepSizeX*x)**2 * (stepSizey*y)**3
end do
end program Hello
You can test it here (set the compiler's Fortran standard to -std=f2008 or -std=gnu).

Scilab fsolve returning incorrect argument (error 98)

I am trying to run fsolve to resolve a dissociation equation but I keep getting this error. I tracked it down to the x(1)^(1/2) term (removing the square root yields no error) but I can't find a way to solve the proper equation I need. The code is below.
T = 2000
Kp = exp(-deltaG/(Ru*T))
function [f]=func(x)
f(1) = 2-x(1)*4 / (3*x(1) - 1)*(x(1))^(1/2) - Kp
endfunction
x0 = [1]
[x,f_x] = fsolve(x0,func)
EDIT: More requested info
The error is
!--error 98 variable returned by scilab argument function is
incorrect
Ru is the gas constant, 8.315.
DeltaG is -135643.
Kp is 3.489e-3.
This is a book example, x should yield 0.3334.
What kind of solved this problem was that I updated scilab to version 6.0.1 from 5.5. The problem is that depending on the initial guess x0 the values of x get really absurd and x0 has to be so close to the real answer that it defeats the purpose of the calculation.
Also I don't have access to Maple, my other alternative would be MATLAB
Using symbolic calculus software like xcas or Maple one can solve your equation symbolycally
There are 3 solutions:
s1=((1/4)*t1+(1/4)*(Kp-2)^2/t1-(1/4)*Kp+1/2)^2
s2=(-(1/8)*t1-(1/8)*(Kp-2)^2/t1-(1/4)*Kp+1/2+(1/2*%i)*sqrt(3)*((1/4)*t1-(1/4)*(Kp-2)^2/t1))^2
s3=(-(1/8)*t1-(1/8)*(Kp-2)^2/t1-(1/4)*Kp+1/2-(1/2*%i)*sqrt(3)*((1/4)*t1-(1/4)*(Kp-2)^2/t1))^2
where
t=sqrt(-Kp*(Kp-4)*(Kp-2)^2)
t1=(-(Kp-2)*(Kp-2*sqrt(2))*(Kp+2*sqrt(2))+4*t)^(1/3);
depending on Kp values some solutions can be complex.

Looped Regressions in SPSS

I have a question, if I am using SPSS, and I have an dependent variable, call it y, and ten independent variables, call them x1 through x10, is there a method to run a loop to check all possible combinations of five variables against the dependent variable, and get a summary of the R^2 values of the model. For instance:
y = independent; x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 = dependent
Regression:
y, (x1,x2,x3,x4,x5)
y, (x1,x2,x3,x4,x6) ...
so on and so on checking all combinations?
Are you sure that you want to do this rather than using a procedure like stepwise regression or best subsets? What's the goal? You will get 252 regressions.
But here's a bit of Python code to do this. The spss.Submit line below should be indented.
begin program.
import spss, itertools
for v in itertools.combinations(['x1','x2','x3','x4','x5',\
'x6','x7','x8','x9','x10'], 5):
spss.Submit("""REGRESSION /DEPENDENT = y /ENTER=%s""" % " ".join(v))
end program.