MATLAB: Transforming a combination of strings as one - string

Let's say I have
a = [ 'i=' num2str(0)]
a =
i=0
and
A = zeros(2);
B = num2str(A)
B =
0 0
0 0
This i=0 is considered a 1x3 matrix: [ i, =, 0]. Now how do I transform this into one element so that I can replace B(1,1) with i=0? I want to get
B =
i=0 0
0 0
(This is the reason why I converted A into string.)
I kept getting this error:
Assignment has more non-singleton rhs dimensions than non-singleton
subscripts
which I suspect was due to a's dimension.
I've tried strcat(a), and some other methods.
Edit:
The motivation behind it is from my attempt to put in labels into a matrix while executing a loop.
This is the last portion of my code:
n5 = length(X(1, :));
n6 = length(X(:, 1)) + 1;
Y = zeros(n6, n5);
Y(2:n6, :) = X;
Z = num2str(Y, 4);
for i = 0:K
a = ['i=' num2str(i)];
Z(1,i+1) = a;
end
X = Z
end
I want the output to show:
i=0 i=1 ... i=K
1.0022 1.0000 ... 1.0000
2.0081 2.0000 ... 2.0000
4.0011 4.0000 ... 4.0000
3.9811 4.0000 ... 4.0000
I'm aware we can format the output in another way, but not in loops. I want to use loops.

Take 2:
I find it difficult to find a way to store in a matrix both strings (i=0...) as well as numbers. I would recommend the use of cell array
sz = size( X );
Z(2,:) = mat2cell( X, sz(1), ones(1,sz(2)) ); % convert each column of X into cell
Z(1,:) = arrayfun( #(x) sprintf('i=%d',x), 0:(sz(2)-1), 'uni', false );
The resulting cell array Z is of size 2x(n5) and would look like:
'i=0' 'i=1' 'i=2' 'i=3' 'i=4'
[5x1 double] [5x1 double] [5x1 double] [5x1 double] [5x1 double]
Where Z{2,ii} is the ii-th column of matrix X.

Related

Find H Index of the nodes of a graph using NetworkX

Definition of H Index used in this algorithm
Supposing a relational expression is represented as y = F(x1, x2, . . . , xn), where F returns an integer number greater than 0, and the function is to find a maximum value y satisfying the condition that there exist at least y elements whose values are not less than y. Hence, the H-index of any node i is defined as
H(i) = F(kj1 ,kj2 ,...,k jki)
where kj1, kj2, . . . , kjki represent the set of degrees of neighboring nodes of node i.
Now I want to find the H Index of the nodes of the following graphs using the algorithm given below :
Graph :
Code (Written in Python and NetworkX) :
def hindex(g, n):
nd = {}
h = 0
# print(len(list(g.neighbors(n))))
for v in g.neighbors(n):
#nd[v] = len(list(g.neighbors(v)))
nd[v] = g.degree(v)
snd = sorted(nd.values(), reverse=True)
for i in range(0,len(snd)):
h = i
if snd[i] < i:
break
#print("H index of " + str(n)+ " : " + str(h))
return h
Problem :
This algorithm is returning the wrong values of nodes 1, 5, 8 and 9
Actual Values :
Node 1 - 6 : H Index = 2
Node 7 - 9 : H Index = 1
But for Node 1 and 5 I am getting 1, and for Node 8 and 9 I am getting 0.
Any leads on where I am going wrong will be highly appreciated!
Try this:
def hindex(g, n):
sorted_neighbor_degrees = sorted((g.degree(v) for v in g.neighbors(n)), reverse=True)
h = 0
for i in range(1, len(sorted_neighbor_degrees)+1):
if sorted_neighbor_degrees[i-1] < i:
break
h = i
return h
There's no need for a nested loop; just make a decreasing list, and calculate the h-index like normal.
The reason for 'i - 1' is just that our arrays are 0-indexed, while h-index is based on rankings (i.e. the k largest values) which are 1-indexed.
From the definition of h-index: For a non-increasing function f, h(f) is max i >= 0 such that f(i) >= i. This is, equivalently, the min i >= 1 such that f(i) < i, minus 1. Here, f(i) is equal to sorted_neighbor_degrees[i - 1]. There are of course many other ways (with different time and space requirements) to calculate h.

Why is a ByVal function changing my variable?

Calling divsig(h) results in changes to h. But divsig is a function that takes a matrix by value and not by reference. How can this happen?
I'm trying to use the sig/divsig functions on matrices of data, for example:
DenseMatrix 4x4-Double ' h before divsig(h)
0.5 0.5 0.5 0.5
0.568811 0.995811 0.418727 0.987232
0.65701 0.269138 0.990942 0.99298
0.716466 0.988705 0.98747 0.999909
divsig(h)
DenseMatrix 4x4-Double ' h after divsig
0.25 0.25 0.25 0.25
0.245265 0.00417185 0.243395 0.0126045
0.225348 0.196703 0.00897602 0.00697036
0.203142 0.0111678 0.0123732 9.14075E-05
Makes no sense to me what so ever, i'm even setting up a new variable called matrix in the function instead of editing 'mat' it's self.
Function divsig(ByVal mat As LinearAlgebra.Double.Matrix)
Dim matrix = mat
For _x = 0 To matrix.RowCount() - 1
For _y = 0 To matrix.ColumnCount() - 1
matrix(_x, _y) = derivsigmoid(matrix(_x, _y))
Next
Next
Return matrix
End Function
Function sigmoid(ByVal x As Double) As Double
Return 1 / (1 + Math.Exp(-x))
End Function
Function derivsigmoid(ByVal x As Double) As Double
Return x * (1 - x)
End Function
Function sig(ByVal mat As LinearAlgebra.Double.Matrix)
Dim matrix = mat
For _x = 0 To matrix.RowCount() - 1
For _y = 0 To matrix.ColumnCount() - 1
matrix(_x, _y) = sigmoid(matrix(_x, _y))
Next
Next
Return matrix
End Function
I have fixed it, turns out matrixes are classes which means passing them ByVal passes the reference anyway. I fixed it by replacing the Dim matrix = mat with
Dim matrix As LinearAlgebra.Double.Matrix = LinearAlgebra.Double.Matrix.Build.DenseOfMatrix(mat)
So matrix becomes a copy of mat instead of just giving the same reference a different identifier.

Iterations over 2d numpy arrays with while and for statements

In the code supplied below I am trying to iterate over 2D numpy array [i][k]
Originally it is a code which was written in Fortran 77 which is older than my grandfather. I am trying to adapt it to python.
(for people interested whatabouts: it is a simple hydraulics transients event solver)
Bear in mind that all variables are introduced in my code which I don't paste here.
H = np.zeros((NS,50))
Q = np.zeros((NS,50))
Here I am assigning the first row values:
for i in range(NS):
H[0][i] = HR-i*R*Q0**2
Q[0][i] = Q0
CVP = .5*Q0**2/H[N]
T = 0
k = 0
TAU = 1
#Interior points:
HP = np.zeros((NS,50))
QP = np.zeros((NS,50))
while T<=Tmax:
T += dt
k += 1
for i in range(1,N):
CP = H[k][i-1]+Q[k][i-1]*(B-R*abs(Q[k][i-1]))
CM = H[k][i+1]-Q[k][i+1]*(B-R*abs(Q[k][i+1]))
HP[k][i-1] = 0.5*(CP+CM)
QP[k][i-1] = (HP[k][i-1]-CM)/B
#Boundary Conditions:
HP[k][0] = HR
QP[k][0] = Q[k][1]+(HP[k][0]-H[k][1]-R*Q[k][1]*abs(Q[k][1]))/B
if T == Tc:
TAU = 0
CV = 0
else:
TAU = (1.-T/Tc)**Em
CV = CVP*TAU**2
CP = H[k][N-1]+Q[k][N-1]*(B-R*abs(Q[k][N-1]))
QP[k][N] = -CV*B+np.sqrt(CV**2*(B**2)+2*CV*CP)
HP[k][N] = CP-B*QP[k][N]
for i in range(NS):
H[k][i] = HP[k][i]
Q[k][i] = QP[k][i]
Remember i is for rows and k is for columns
What I am expecting is that for all k number of columns the values should be calculated until T<=Tmax condition is met. I cannot figure out what my mistake is, I am getting the following errors:
RuntimeWarning: divide by zero encountered in true_divide
CVP = .5*Q0**2/H[N]
RuntimeWarning: invalid value encountered in multiply
QP[N][k] = -CV*B+np.sqrt(CV**2*(B**2)+2*CV*CP)
QP[N][k] = -CV*B+np.sqrt(CV**2*(B**2)+2*CV*CP)
ValueError: setting an array element with a sequence.
Looking at your first iteration:
H = np.zeros((NS,50))
Q = np.zeros((NS,50))
for i in range(NS):
H[0][i] = HR-i*R*Q0**2
Q[0][i] = Q0
The shape of H is (NS,50), but when you iterate over a range(NS) you apply that index to the 2nd dimension. Why? Shouldn't it apply to the dimension with size NS?
In numpy arrays have 'C' order by default. Last dimension is inner most. They can have a F (fortran) order, but let's not go there. Thinking of the 2d array as a table, we typically talk of rows and columns, though they don't have a formal definition in numpy.
Lets assume you want to set the first column to these values:
for i in range(NS):
H[i, 0] = HR - i*R*Q0**2
Q[i, 0] = Q0
But we can do the assignment whole rows or columns at a time. I believe new versions of Fortran also have these 'whole-array' functions.
Q[:, 0] = Q0
H[:, 0] = HR - np.arange(NS) * R * Q0**2
One point of caution when translating to Python. Indexing starts with 0; so does ranges and np.arange(...).
H[0][i] is functionally the same as H[0,i]. But when using slices you have to use the H[:,i] format.
I suspect your other iterations have similar problems, but I'll stop here for now.
Regarding the errors:
The first:
RuntimeWarning: divide by zero encountered in true_divide
CVP = .5*Q0**2/H[N]
You initialize H as zeros so it is normal that it complains of division by zero. Maybe you should add a conditional.
The third:
QP[N][k] = -CV*B+np.sqrt(CV**2*(B**2)+2*CV*CP)
ValueError: setting an array element with a sequence.
You define CVP = .5*Q0**2/H[N] and then CV = CVP*TAU**2 which is a sequence. And then you try to assign a derivate form it to QP[N][K] which is an element. You are trying to insert an array to a value.
For the second error I think it might be related to the third. If you could provide more information I would like to try to understand what happens.
Hope this has helped.

How do I change a matrix entry and return the matrix

I want to define a function which takes three parameters, the coordinates i, j and the matrix itself.
It has to change the entry at the given position (i,j) and return the new matrix.
My predefined Matrix:
fieldA 1 1 = 0
fieldA 1 2 = 1
fieldA 2 1 = 1
fieldA 2 2 = 0
My first attempt was the following code & error:
changeValue i j matrix =
do matrix i j <- 0
return matrix
test.hs:113:12: error:
Parse error in pattern: matrix
Possibly caused by a missing 'do'?
My second attemt was the following code & error:
changeValue i j matrix =
map (\a b -> if a == i && b == j then matrix i j <- 0 else matrix i j <- matrix i j) matrix
test.hs:113:58: error:
parse error on input ‘<-’
Perhaps this statement should be within a 'do' block?
I think the solution is simple but I'm an absolutely beginner in Haskell and
I would appreciate any kind of help
Perhaps you want something like this:
changeValue :: Int -> Int -> Matrix -> Matrix
changeValue i j matrix = matrix2
where
matrix2 i2 j2 | i2==i && j2==j = 0
| otherwise = matrix i2 j2
It is recommended to always add type signatures to your top level bindings. This can greatly help clarifying one's ideas, as well as helping the compiler to provide good error messages.

How to round up in progress programming

I am writing a report for an MRP program and it contains a field I calculate for the quantity to order. I need to round the number up if it is a decimal point.
For example: 2.33 needs to be rounded up to 3 and so on.
I have tried
oder = round(order,0).
but that just get me 2.00
I need that number to be rounded up to the next whole number.
function roundUp returns integer ( x as decimal ):
if x = truncate( x, 0 ) then
return integer( x ).
else
return integer( truncate( x, 0 ) + 1 ).
end.
display roundUp( 2.33 ).
x = round(n + 0.4999999999, 0)
... should work for all for negative values of n too
n = -2.0000001 ... x = -2
n = -2.5 ... x = -2
n = -2.9999999999 ... x = -2
roundUp() resolves to -1 in all the above negative values of n
This will work for negative values too. Return value is intentionally kept as Integer, you can keep it as Decimal too.
function roundUp returns integer
(
input in-value as DECIMAL
):
def var x as decimal no-undo.
def var y as decimal no-undo.
if in-value < 0 then
DO:
x = truncate(in-value,0).
y = in-value - x.
if abs(y) <= 0.5 then
return INTEGER(x).
else
return INTEGER(round(in-value,0)).
END.
ELSE
return INTEGER(round(in-value,0)).
end function.
Use the following:
DEF VAR X AS decimal.
DEF VAR Y AS integer.
update
x with frame a.
Y = X - 1.
display y.
IF (( X - Y ) < 0.5)
THEN do:
DISPLAY round(x,0) + 1.
end.
ELSE DO :
DISPLAY round(x,0).
end.

Resources