2

I have the following function handle uppercase K and array of lowercase k and gamma values.

N = 3; k = randi([1,1000],N+1,1,"double"); gamma = randi([1,100],N+1,1,"double"); K = @(x) [zeros(N,N)]; 

I need to populate this function handle with specific values of lowercase k and x. For this example with N=3, the corresponding uppercase K matrix is: enter image description here

Looking at this uppercase K matrix, one can see that the pattern is to start with the first two elements in the matrix in green, copy their values, shift them to the right once, shift them down once, and increase the index of each variable in the elements by 1.

I would like to return uppercase K using the following function:

function K = karray (k,N) K = @(x) [zeros(N,N)]; for i=1:1:N for j=1:1:N K(i,j) = (k(i)*gamma(i)+k(i+1)*gamma(i+1))*x(i)^2+k(i)+k(i+1); K(i,j+1) = -3*k(i+1)*gamma(i+1)*x(i)^2-k(i+1); end end end 

My initial thought was to use a nested for loop to populate uppercase K, but since K is a function handle, I can't simply access each element in K by using K(i,j). I think that my method for populating K is correct, but I'm not sure how to properly access each element in K.

EDIT: How do you remove the N+1th gamma and k terms from the uppercase K matrix? For example, for N=3, how do you remove k_4 and gamma_4 to get: enter image description here

10
  • 1
    What is x here?
    – rahnema1
    CommentedOct 15, 2023 at 2:21
  • 3
    As I commented to your other post, the difficulty has nothing to do with K being a handle, it is that you’re trying to do everything in an anonymous function. You can create a regular named function, and get the handle to that. In a named function you can use loops and anything else you might need.CommentedOct 15, 2023 at 2:28
  • 2
    Also, I’m confused by your example. The code doesn’t produce the zeros in the equation, and each loop iteration of j overwrites a result from the previous iteration. That cannot be right.CommentedOct 15, 2023 at 2:33
  • @rahnema1 x is just a variable that represents the displacement of masses in a mass-spring-damper system. This K matrix ends up getting passed to MATLAB’s ODE45 function to solve for the displacement of each mass x(1), x(2), x(3), etc.CommentedOct 15, 2023 at 6:02
  • 1
    Yes, karrray is a named function. But inside you create an anonymous function K to return. Instead return the handle to a named function, as in the answer below.CommentedOct 15, 2023 at 14:22

1 Answer 1

4

Here spdiags is used to create the diagonal matrix. Otherwise you may use for loops to fill the diagonal matrix.

function K = karray(k, gamma, N) K = @(x) make_diagonal(x, k, gamma, N); end function out = make_diagonal(x, k, gamma, N) x = x(:); x = [x(1:N); 0]; ck = circshift(k, -1); cg = circshift(gamma, -1); cx = circshift(x, -1); ccx =circshift(x, 1); d1 = -3 .* ck .* cg .* cx .^ 2 - ck; d2 = (k .* gamma + ck .* cg) .* x .^ 2 + k + ck; d3 = -3 .* k .* ccx .^ 2 - k; out = full(spdiags([d1 d2 d3], -1:1, N, N)); end 

EDIT: In response to the edited question of how do you remove k_4 and gamma_4? You need to set ck(end) = 0; and cg(end) = 0; before computing d1, d2 and d3.

4
  • 1
    This is a beautiful implementation. I now see what you mean by named and anonymous functions @CrisLuengoCommentedOct 15, 2023 at 16:45
  • Why do you append 0 to x here with x = [x(1:N); 0]? Why don't you just do x = x(1:N)?CommentedJan 30, 2024 at 18:45
  • I think a zero is appended to x to make its length the same as the length of k.
    – rahnema1
    CommentedJan 30, 2024 at 19:35
  • Do you know how to change make_diagonal() to get the altered K matrix (see edit in original post)? @rahnema1CommentedMay 16, 2024 at 16:55

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.