List of digraphs in MATLAB - arrays

I am a beginner in MATLAB.
I have a function that takes an integer as input and returns a directed graph (digraph); I therefore have a list of integers L, and would like to create a list of digraphs derived from such integers.
I have a function create_graph(n) that returns such digraph.
What I am currently doing is:
Gs = [];
for i=1:length(L)
x = L(i);
G = create_graph(x);
Gs(end + 1) = G;
end
And it returns an error:
Unable to perform assignment because value of type 'digraph' is not convertible to 'double'.
Error in dummy_code (line 20)
Gs(end + 1) = G;
Caused by:
Error using double
Conversion to double from digraph is not possible.
Another error appear if I initialize a dummy digraph, that is:
Gs = [digraph([1,1;1,1])];
for i=1:length(L)
x = L(i);
G = create_graph(x);
Gs(end + 1) = G;
end
Error using indexing
Unsupported graph indexing.
What I would like to do is something close to the python code:
Gs = [create_graph(x) for x in L]

Related

Issues with arrays and matlab coder

I've been working on creating c code with Matlab-coder. I have a function called melfunction that gives an error for line 20 of the code below.
function [ c ] = melfunction( x )
bank=melbankm(24,256,8000,0,0.4,'t');
bank=full(bank); %full() convert sparse matrix to full matrix
bank=bank/max(bank(:));
w=1+6*sin(pi*[1:12]./12);
w=w/max(w);
xx=double(x);
xx=filter([1-0.9375],1,xx);
xx=enframe(xx,256,80)
p = zeros(1,256); < --------------------- SOLUTION CHANGE TO p = zeros(256)
m = zeros(1,12); < --------------------- SOLUTION CHANGE TO p = zeros(12)
for i=1:size(xx,1)
y=xx(i,:);
s=y'.*hamming(256);
t=abs(fft(s));
t=t.^2;
p(i,:) = t; < --------------------------- ERROR HERE
c1=dctcoef*log(bank*t(1:129));
c2=c1.*w';
m(i,:)=c2;
end
error message looks like this
Error using melfunction (line 20)
Index exceeds array dimensions. Index value 2 exceeds valid range [1-1] of array p.
Error in TESTINPUTS (line 2)
d0=melfunction(x)
If I come up with an answer I will post it when I find one.
Ok so I messed with it a bit and found that I believe I did not know how to correctly initialize p and m . In an attempt to add these lines of code for another part of Matlab-Coder I initialized the p and m variables incorrectly. This is the original initialization.
p = zeros(1,256);
m = zeros(1,12);
this is what I changed it too.
p = zeros(256);
m = zeros(12);

Finite element analysis, 1D

I want the output to be values of C, at all range of i and t in the loops.
When I run it, I get error in sym/subref, L_tilde, idx.
I do not know what it means.
syms C;
alphaX=0.05;
DiffCoef = 5*10^-5
v = 0.1;
L = 10; xZones = 100;
dx = L/xZones;
T = 150;
u = 0.1;
dt= 0.005;
t = 150;
D = DiffCoef + (alphaX * u);
for i = 1:xZones
for t = 1:xZones
(C(i,t+dt) - C(i,t))/dt = -u(C(i+1,t +dt) - C(i,t+dt))/dx + D(C(i+1,t+dt) - 2*(C(i,t+dt) + C(i-1,t+dt)))/(dx)^2
end
end
Assuming this is Matlab code, there are some problems:
1) you cannot assign two outputs so the statement
(C(i,t+dt) - C(i,t))/dt = ...
is illegal. Matlab expressions can only return one output (without using for example "deal"), so in your case you would have to rearrange your expression as maybe
C(i,t+dt) = ...
C(i,t) = ...
Moreover, as this seems it is a time difference formula typically anything f(t+dt) is the unknown (left hand side), and f(t) are the known values as previous time step (right hand side) so that
f(t+dt) = dt*old_rhs - f(t)
In your case you have prescribed _C(i,t_dt)_ which seems very unusual, so please check your equations.

How to recursively fill an array with functions?

So I'm trying to write a function to generate Hermite polynomials and it's doing something super crazy ... Why does it generate different elements for h when I start with a different n? So inputting Hpoly(2,1) gives
h = [ 1, 2*y, 4*y^2 - 2]
while for Hpoly(3,1) ,
h = [ 1, 2*y, 4*y^2 - 4, 2*y*(4*y^2 - 4) - 8*y]
( (4y^2 - 2) vs (4y^2 - 4) as a third element here )
also, I can't figure out how to actually evaluate the expression. I tried out = subs(h(np1),y,x) but that did nothing.
code:
function out = Hpoly(n, x)
clc;
syms y
np1 = n + 1;
h = [1, 2*y];
f(np1)
function f(np1)
if numel(h) < np1
f(np1 - 1)
h(np1) = 2*y*h(np1-1) - 2*(n-1)*h(np1-2);
end
end
h
y = x;
out = h(np1);
end
-------------------------- EDIT ----------------------------
So I got around that by using a while loop instead. I wonder why the other way didn't work ... (and still can't figure out how to evaluate the expression other than just plug in x from the very beginning ... I suppose that's not that important, but would still be nice to know...)
Sadly, my code isn't as fast as hermiteH :( I wonder why.
function out = Hpoly(n, x)
h = [1, 2*x];
np1 = n + 1;
while np1 > length(h)
h(end+1) = 2*x*h(end) - 2*(length(h)-1)*h(end-1);
end
out = h(end)
end
Why is your code slower? Recursion is not necessarily of Matlab's fortes so you may have improved it by using a recurrence relation. However, hermiteH is written in C and your loop won't be as fast as it could be because you're using a while instead of for and needlessly reallocating memory instead of preallocating it. hermiteH may even use a lookup table for the first coefficients or it might benefit from vectorization using the explicit expression. I might rewrite your function like this:
function h = Hpoly(n,x)
% n - Increasing sequence of integers starting at zero
% x - Point at which to evaluate polynomial, numeric or symbolic value
mx = max(n);
h = cast(zeros(1,mx),class(x)); % Use zeros(1,mx,'like',x) in newer versions of Matlab
h(1) = 1;
if mx > 0
h(2) = 2*x;
end
for i = 2:length(n)-1
h(i+1) = 2*x*h(i)-2*(i-1)*h(i-1);
end
You can then call it with
syms x;
deg = 3;
h = Hpoly(0:deg,x)
which returns [ 1, 2*x, 4*x^2 - 2, 2*x*(4*x^2 - 2) - 8*x] (use expand on the output if you want). Unfortunately, this won't be much faster if x is symbolic.
If you're only interested in numeric results of the the polynomial evaluated at particular values, then it's best to avoid symbolic math altogether. The function above valued for double precision x will be three to four orders of magnitude faster than for symbolic x. For example:
x = pi;
deg = 3;
h = Hpoly(0:deg,x)
yields
h =
1.0e+02 *
0.010000000000000 0.062831853071796 0.374784176043574 2.103511015993210
Note:
The hermiteH function is R2015a+, but assuming that you still have access to the Symbolic Math toolbox and the Matlab version is R2012b+, you can also try calling MuPAD's orthpoly::hermite. hermiteH used this function under the hood. See here for details on how to call MuPAD functions from Matlab. This function is a bit simpler in that it only returns a single term. Using a for loop:
syms x;
deg = 2;
h = sym(zeros(1,deg+1));
for i = 1:deg+1
h(i) = feval(symengine,'orthpoly::hermite',i-1,x);
end
Alternatively, you can use map to vectorize the above:
deg = 2;
h = feval(symengine,'map',0:deg,'n->orthpoly::hermite(n,x)');
Both return [ 1, 2*x, 4*x^2 - 2].

Error SML NJ-Operator and Operand don't agree

When I try to compile my ML Program ,I get an error saying:"Operator and Operand don't agree".
candidates.sml:78.8-78.40 Error: operator and operand don't agree [tycon mismatch]
operator domain: int * (int * 'Z * 'Y) list
operand: int * (int * real) list
in expression:
tr (n,candidates)
I understand the error but I can't find a solution.
The part of the code where I get the error is:
fun agonas fileName =
let
fun tr(n,[])=[]
| tr(n,((a,b,c)::d))=((n-a+1),b,c)::(tr(n,d))
val (n,l,candidates) = parse fileName
val cand = tr(n,candidates)
in
my_solution(l,cand)
end;
,where the candidates are related with the part below:
fun parse file =
let
(* a function to read an integer from an input stream *)
fun next_int input =
Option.valOf (TextIO.scanStream (Int.scan StringCvt.DEC) input)
(* a function to read a real that spans till the end of line *)
fun next_real input =
Option.valOf (TextIO.inputLine input)
(* open input file and read the two integers in the first line *)
val stream = TextIO.openIn file
val n = next_int stream
val l = next_int stream
val _ = TextIO.inputLine stream
(* a function to read the pair of integer & real in subsequent lines *)
fun scanner 0 acc = acc
| scanner i acc =
let
val d = next_int stream
val (SOME v) = Real.fromString (next_real stream)
in
scanner (i - 1) ((d, v) :: acc)
end
in
(n, l, rev(scanner n []))
end;
fun my_solution ( n , l ,candidates ) = [2 ,3 ,5 ,4 ,6]
fun agonas fileName = my_solution ( parse fileName )
I would appreciate it if you could find the mistake.Thanks in advance.
The problem is that parse, using scanner, builds a list of pairs — (int * real) list — while tr expects to get a list of triples — (int * 'Z * 'Y) list.
Not knowing what tr is supposed to do, the quick and dirty fix would be to change
tr(n,((a,b,c)::d))=((n-a+1),b,c)::(tr(n,d))
into
tr(n,((a,b)::d))=((n-a+1),b)::(tr(n,d))
But that may be the wrong solution - it depends on what the code is supposed to do.
(Sometimes it helps to explicitly write out the types yourself - even before writing the code - instead of relying on type inference to catch the places where you need to do some more thinking.)
The error message says it all: the offending line calls trans, and that is a function that expects two arguments, the second being a list of triples. However, you are passing it a list of pairs instead (as produced by your scanner function).
You didn't show us the trans function, so I cannot be more specific about what the appropriate fix would be.

"Error in MuPAD command: DOUBLE cannot convert the input expression into a double array"

I've tried to find the answer to this simple for loop question but I can't find any tutorials on it. I'm trying to calculate a specific entry of a column vector but the error "Error in MuPAD command: DOUBLE cannot convert the input expression into a double array" keeps showing up. I'm pretty sure that both entries in the for loop should come up as scalar functions of u1,...,u20 but I must be doing something wrong. My script reads as follows:
U = sym('u', [21 1]);
P(1,1) = 1;
Q(1,1) = 0;
for k = 1:20
P(k+1,1) = 1/20*(-.3*P(k,1) +.65*Q(k,1)+U(k,1))+P(k,1);
Q(k+1,1) = 1/20*(-.65*Q(k,1) + .3*P(k,1)-U(k,1))+Q(k,1);
end
P(21,1)
Q(21, 1)
Any help would be greatly appreciated.
As David suggests, maybe:
U = sym('u', [21 1]);
syms P Q
for k = 1:20
P(k+1,1) = 1/20*(-.3*P(k,1) +.65*Q(k,1)+U(k,1))+P(k,1);
Q(k+1,1) = 1/20*(-.65*Q(k,1) + .3*P(k,1)-U(k,1))+Q(k,1);
end
P(21,1)
Q(21, 1)
Saw a similar explanation elsewhere on stack overflow. 2 variables in an array

Resources