Unable to correctly solve ODE with Scilab - ode

I want to solve the following differential equation using scilab:
f(x)=sin(x);
with initial values as x0=0, y0=0;
What I have tried is this:
// Define x
x0=0; y0=0;
xinc=0.001; xf=6; x=x0:xinc:xf;
// Define differential equation
deff('y=f(x)','y=sin(x)');
// Solve differential equation
ydiff=ode(y0,x0,x,y);
However, I get error:
-->exec('C:\Users\Saaama\Desktop\sinx().sce', -1)
ydiff=ode(y0,x0,x,y);
!--error 4
Undefined variable: y
at line 9 of exec file called by :
exec('C:\Users\Saima\Desktop\sinx().sce', -1)
I have also tried
ydiff=ode(y0,x0,x,f);
Still I get the same error on ode function.

ode expects a function that takes parameters time and space, dotx=f(t,x), even if the time is not used in the function.
But from context you intent x to be the time variable, so that the problem is a simple quadrature. Then you need to use
deff('doty=f(x,y)','doty=sin(x)');
or the long form
function doty=f(x,y)
doty=sin(x)
endfunction

Related

Eigen3 : dynamic matrix along one dimension only : failure to contruct

I can easily define a matrix type of fixed lines number and undefined columns number :
typedef Matrix<double, 6, Dynamic> dMat6rowsNCols;
dMat6rowsNCols M1;
But I couldn't figure out how to instanciate it, those attempts don't compile :
M1.Zero(4);
M1 = dMat6rowsNCols::Zero(4);
May I ask you some hints ?
Cheers
Sylvain
From the documentation of DenseBase::Zero(Index):
This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column.
You have to use DenseBase::Zero(Index, Index):
M1 = dMat6rowsNCols::Zero(6, 4);
If you are using the current Eigen trunk you can use Eigen::NoChange for some functions, e.g.
M1.setZero(Eigen::NoChange, 4);
As a side note: Calling M1.Zero does not call the member function that sets all coefficients to 0 but is a less common way of calling the static function DenseBase::::Zero. You are probably looking for M1.setZero.

I don't comprehend why Scilab is giving me "syntax error, unexpected ;"

Well, I got this Newton's Method for multiple variables code that was modified by me to function with 4 variables instead of 2, but I keep getting the error
Syntax error, unexpected ;
referencing line 9 which is the Jacobian matrix from the partial derivatives of the equations on function F. Every " " is another column and every ";" is another line.
clear;clc
function z=F(p1,p2,p3,p4)
z(1)=0.3*(500-p1)^0.5-0.2*(p1-p2)^0.5+0.2*(p1-p3)^0.5
z(2)=0.2*(p1-p2)^0.5-0.1*(p2-p4)^0.5+0.2*(p2-p3)^0.5
z(3)=0.1*(p1-p3)^0.5-0.2*(p3-p2)^0.5+0.1*(p3-p4)^0.5
z(4)=0.1*(p2-p4)^0.5+0.1*(p3-p4)^0.5-0.2*(p4)^0.5
endfunction
function z=J(p1,p2,p3,p4) //Jacobiano
z=[-0.3/(2*sqrt(500-p1))-0.2/(2*sqrt(p1-p2))+0.2/(2*sqrt(p1-p3)) 0.2/(2*sqrt(p1-p2)) -0.2/(2*sqrt(p1-p3)) 0;0.2/(2*sqrt(p1-p2)) -0.2/(2*sqrt(p1-p2))-0.1/(2*sqrt(p2-p4))+0.2/(2*sqrt(p2-p3) -0.2/(2*sqrt(p2-p3)) -0.1/(2*sqrt(p2-p4));0.1/(2*sqrt(p1-p3)) 0.2/(2*sqrt(p3-p2)) -0.1/(2*sqrt(p1-p3))-0.2/(2*sqrt(p3-p2))+0.1(2*sqrt(p3-p4)) -0.1/(2*sqrt(p3-p4));0 0.1/(2*sqrt(p2-p4)) 0.1/(2*sqrt(p3-p4)) -0.1/(2*sqrt(p2-p4))-0.1/(2*sqrt(p3-p4))-0.2/(2*sqrt(p4))]
endfunction
The code doesn't end here, but the error is certainly in the format I used in the 4x4 Jacobian matrix or in the function itself, I just don't get why is wrong.
Appreciate any help.
You forgot to close a parenthesis in column 191 of line 9, and you also forgot an operator on column 319.
If you're creating a matrix in which the elements are results of operations, you'd better use commas instead of blank spaces to separate them. You should also be using ... to break the matrix definition in more than one line to improve readability. Your Jacobian function would be a lot easier to debug if it were written like this:
function z=J(p1,p2,p3,p4) //Jacobiano
z=[-0.3/(2*sqrt(500-p1))-0.2/(2*sqrt(p1-p2))+0.2/(2*sqrt(p1-p3)),...
0.2/(2*sqrt(p1-p2)),...
-0.2/(2*sqrt(p1-p3)),...
0;...
...
0.2/(2*sqrt(p1-p2)),...
-0.2/(2*sqrt(p1-p2))-0.1/(2*sqrt(p2-p4))+0.2/(2*sqrt(p2-p3),...
-0.2/(2*sqrt(p2-p3)),...
-0.1/(2*sqrt(p2-p4));...
...
0.1/(2*sqrt(p1-p3)),...
0.2/(2*sqrt(p3-p2)),...
-0.1/(2*sqrt(p1-p3))-0.2/(2*sqrt(p3-p2))+0.1(2*sqrt(p3-p4)),...
-0.1/(2*sqrt(p3-p4));...
...
0,...
0.1/(2*sqrt(p2-p4)),...
0.1/(2*sqrt(p3-p4)),...
-0.1/(2*sqrt(p2-p4))-0.1/(2*sqrt(p3-p4))-0.2/(2*sqrt(p4))]
endfunction
In this style, your mistakes can be easily spotted: notice the missing ) in line 8, and the missing / in line 14.

Assignment problems with simple random number generation in Modelica

I am relatively new to Modelica (Dymola-environment) and I am getting very desperate/upset that I cannot solve such a simple problem as a random number generation in Modelica and I hope that you can help me out.
The simple function random produces a random number between 0 and 1 with an input seed seedIn[3] and produces the output seed seedOut[3] for the next time step or event. The call
(z,seedOut) = random(seedIn);
works perfectly fine.
The problem is that I cannot find a way in Modelica to compute this assignment over time by using the seedOut[3] as the next seedIn[3], which is very frustrating.
My simple program looks like this:
*model Randomgenerator
Real z;
Integer seedIn[3]( start={1,23,131},fixed=true), seedOut[3];
equation
(z,seedOut) = random(seedIn);
algorithm
seedIn := seedOut;
end Randomgenerator;*
I have tried nearly all possibilities with algorithm assignments, initial conditions and equations but none of them works. I just simply want to use seedOut in the next time step. One problem seems to be that when entering into the algorithm section, neither the initial conditions nor the values from the equation section are used.
Using the 'sample' and 'reinit' functions the code below will calculate a new random number at the frequency specified in 'sample'. Note the way of defining the "start value" of seedIn.
model Randomgenerator
Real seedIn[3] = {1,23,131};
Real z;
Real[3] seedOut;
equation
(z,seedOut) = random(seedIn);
when sample(1,1) then
reinit(seedIn,pre(seedOut));
end when;
end Randomgenerator;
The 'pre' function allows the use of the previous value of the variable. If this was not used, the output 'z' would have returned a constant value. Two things regarding the 'reinint' function, it requires use of 'when' and requires 'Real' variables/expressions hence seedIn and seedOut are now defined as 'Real'.
The simple "random" generator I used was:
function random
input Real[3] seedIn;
output Real z;
output Real[3] seedOut;
algorithm
seedOut[1] :=seedIn[1] + 1;
seedOut[2] :=seedIn[2] + 5;
seedOut[3] :=seedIn[3] + 10;
z :=(0.1*seedIn[1] + 0.2*seedIn[2] + 0.3*seedIn[3])/(0.5*sum(seedIn));
end random;
Surely there are other ways depending on the application to perform this operation. At least this will give you something to start with. Hope it helps.

How to setup my function with blockproc to process the image in parts?

I have an image:
I want to divide this image into 3 equal parts and calculate the SIFT for each part individually and then concatenate the results.
I found out that Matlab's blockproc does just that, but I do not know how to get it to work with my function. Here is what I have:
[r c] = size(image);
c_new = floor(c/3); %round it
B = blockproc(image, [r c_new], #block_fun)
So according to Matlabs documentation the function, block_fun will be applied to the original image in blocks of size r and c_new.
this is what I wrote as block_fun
function feats = block_fun(img)
[keypoints, descriptors] = vl_sift(single(img));
feats = descriptors;
end
So, my matrix B should be a concatenation of the SIFT descriptors of all three parts of the same image? right?
But the error that I get when I run the command:
B = blockproc(image, [r c_new], #block_fun)
Function BLOCKPROC encountered an error while evaluating the user
supplied function handle, FUN.
The cause of the error was:
Error using single Conversion to single from struct is not possible.
For your custom function, blockproc sends in a structure where the image data is stored in a field called data. As such, you simply need to change your function so that it accesses the data field in the input. Like so:
function feats = block_fun(block_struct) %// Change
[keypoints, descriptors] = vl_sift(single(block_struct.data)); %// Change
feats = descriptors;
end
This error is caused by the fact that the function that is called via its handle by blockproc expects a block struct.
The real problem is that blockproc will attempt to concatenate all results and you will have a different set of 128xN feature vectors for each block, which blockproc doesn't allow.
I think that using im2col and reshape would be much more simple.

What causes "Jacobian matrix" to be singular in SAS?

I have a simple SAS (version 9.2) program as follows,
proc model;
cdf('normal',log(V/100)+1)=0.5;
bounds V>0;
solve V/solveprint;
run;
It throws exception that says jacobian matrix to be singular,
The Newton method Jacobian matrix of partial derivatives of the
equations with respect to the variables to be solved is singular.
What is the possible cause of this error?
Update: I have simplified the problem a bit. When modified to "cdf('normal', X)=0.5", it works without exception.
Update2: bounds is updated to V>0; but exception still there
What input data set are you passing to proc model? For example, this code works consistently:
data a;
v=100;
run;
proc model data=a;
cdf('normal',log(V/100)+1) = 0.5;
bounds V>0;
solve V / solveprint;
run;
quit;
And gives a solution of V=36.78794
But changing the input data somewhat (see below) will consistently give a singular Jacobian matrix error.
data a;
v=0.00001;
run;
proc model data=a;
cdf('normal',log(V/100)+1) = 0.5;
bounds V>0;
solve V / solveprint;
run;
quit;
You are asking SAS to solve a function that has no solution. You are asking for the value of V>1000 that makes this equation true. But there are no such values because log(1000/100+1) is about 3.3, and the CDF of a Normal random variable with mean 0 and standard deviation 1 evaluated at 3.3 is 0.9995. Any larger value of V will just move the function closer to 1, not toward 0.5, so there is no answer to your question.
By telling you that the matrix of partial derivatives is singular, SAS is just using fancy math speak for "your function doesn't have a solution". (Really what it's saying is, "I've turned your question into an equivalent maximization problem, and that problem doesn't have a maximum, so I can't help you.")

Resources