필터 지우기
필터 지우기

vectorized operations on symbolic functions

조회 수: 19 (최근 30일)
Muhammad Uzair
Muhammad Uzair 2024년 2월 19일
편집: Torsten 2024년 4월 21일 11:51
Hi, Can we apply vectorized operations on symbolic functions to avoid loops?
syms x1 x2 x3; % symbolic variables
y = x1^3/3 + x2^2/2 - x3; % symbolic function y
X = rand(500,3) % each row representing a combination of x1 x2 x3
I used for loop, but it is taking more time.
y_values = zeros(size(X,1))
for ii = 1:size(X,1)
y_values(ii) = subs(y, [x1, x2, x3], X(ii,:));
end
I have tried following but since there is inconsistency between sizes of old and new it don't work for me.
y_values = subs(y, [x1, x2, x3], X); % Evaluate the function for all combinations in matrix X
Thanks

채택된 답변

Hassaan
Hassaan 2024년 2월 19일
편집: Hassaan 2024년 2월 19일
syms x1 x2 x3; % symbolic variables
y = x1^3/3 + x2^2/2 - x3; % symbolic function y
% Generate a random matrix X with 500 rows and 3 columns
X = rand(500, 3); % each row representing a combination of x1 x2 x3
% Evaluate the symbolic function y for each row in X
% Convert the matrix X to a cell array where each row is a separate cell
X_cell = num2cell(X, 2);
% Use cellfun to apply the subs function to each cell (row) of X_cell
y_values = cellfun(@(row) subs(y, [x1, x2, x3], row), X_cell);
% Convert y_values to a double array if needed
y_values = double(y_values);
disp(y_values(1:10))
-0.6359 -0.1162 -0.2625 -0.1633 -0.8502 -0.9749 0.4400 -0.2646 -0.2648 -0.2096
-----------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
It's important to note that the advice and code are based on limited information and meant for educational purposes. Users should verify and adapt the code to their specific needs, ensuring compatibility and adherence to ethical standards.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
Feel free to contact me.
  댓글 수: 2
Muhammad Uzair
Muhammad Uzair 2024년 2월 19일
Thank you for your helpful answer! It has improved my understanding of the topic. I am currently working on optimization using a generic algorithm. Unfortunately, my evaluation function is taking too much time for a single iteration, which is becoming unaffordable due to the high time cost. I suspect that most of the time is consumed in finding the Jacobian matrix value from the symbolic function. I have attempted using cell operations, but since the Jacobian is a square matrix (3x6) in my case, it cannot provide a single output value. I have considered decomposing the matrix into 18 functions and finding their value arrays using cells, but this approach seems computationally expensive. Could you please guide me on a more efficient way to handle this?
Dyuman Joshi
Dyuman Joshi 2024년 4월 21일 5:58
Note that using num2cell and subsequently cellfun is not efficient.

댓글을 달려면 로그인하십시오.

추가 답변 (5개)

Matt J
Matt J 2024년 2월 19일
편집: Matt J 2024년 2월 19일
syms x1 x2 x3; % symbolic variables
y = x1^3/3 + x2^2/2 - x3; % symbolic function y
X = rand(500,3); % each row representing a combination of x1 x2 x3
ynum=matlabFunction(y) %convert to a numeric function
ynum = function_handle with value:
@(x1,x2,x3)-x3+x1.^3./3.0+x2.^2./2.0
yvalues=ynum(X(:,1),X(:,2),X(:,3))
yvalues = 500×1
-0.2351 0.0690 -0.4473 -0.5099 -0.6491 -0.5465 -0.7009 -0.3988 0.0451 -0.2412

Dyuman Joshi
Dyuman Joshi 2024년 2월 19일
Better to use a function handle -
x = rand(500,3);
y = @(x) x(:,1).^3/3 + x(:,2).^2/2 - x(:,3);
out1 = y(x)
out1 = 500×1
-0.3891 0.3727 -0.1355 -0.1076 -0.7001 -0.4155 -0.0613 -0.3197 -0.8788 -0.0225
For more information, refer to these documentation pages -
  댓글 수: 2
Muhammad Uzair
Muhammad Uzair 2024년 2월 19일
Thank you for your assistance. In my current scenario, I have a square matrix that I need to compute for various input values. I’m unsure whether function handles would be suitable for this case. Additionally, the output matrix will be of size 3x6. Is there a way to obtain individual pages of the output matrix? Specifically, I’m aiming for an output structure of 3x6xn, where ‘n’ represents the number of input combinations.
Christine Tobler
Christine Tobler 2024년 2월 19일
Your best approach then might be to make your input variables have the individual pages already as a third dimension:
x = randn(3, 1, 500);
y = randn(1, 6, 500);
z = x.*y;
size(z)
ans = 1×3
3 6 500
The formula here is of course completely made up, it would depend on what your formula for this 3x6 matrix is.

댓글을 달려면 로그인하십시오.


Aquatris
Aquatris 2024년 2월 19일
편집: Aquatris 2024년 2월 19일
Yet another method, you can define your symbolic parameter as a matrix symbolic
n = 500;
X = sym('X', [500 3]);
% I assume here you want a element wise power ('.^') instead of matrix power
y = X(:,1).^3/3 + X(:,2).^2/2 - X(:,3); % symbolic function y
X_val = rand(500,3); % each row representing a combination of x1 x2 x3
y_values = double(subs(y, X, X_val)) % Evaluate the function for all combinations in matrix X
y_values = 500×1
-0.4390 -0.7329 -0.2091 -0.6554 -0.7112 -0.7845 0.1304 -0.5119 -0.1252 -0.3767
size(y_values)
ans = 1×2
500 1

Walter Roberson
Walter Roberson 2024년 2월 19일
syms x1 x2 x3; % symbolic variables
y = x1^3/3 + x2^2/2 - x3; % symbolic function y
X = rand(500,3); % each row representing a combination of x1 x2 x3
y_values = double(subs(y, {x1, x2, x3}, {X(:,1), X(:,2), X(:,3)}));
y_values(1:5)
ans = 5×1
-0.5223 0.1043 0.4163 -0.1058 -0.3735

Torsten
Torsten 2024년 4월 21일 11:48
편집: Torsten 2024년 4월 21일 11:51
rng("default")
syms x1 x2 x3; % symbolic variables
y = x1^3/3 + x2^2/2 - x3; % symbolic function y
X = rand(500,3) % each row representing a combination of x1 x2 x3
X = 500x3
0.8147 0.5822 0.6312 0.9058 0.5407 0.3551 0.1270 0.8699 0.9970 0.9134 0.2648 0.2242 0.6324 0.3181 0.6525 0.0975 0.1192 0.6050 0.2785 0.9398 0.3872 0.5469 0.6456 0.1422 0.9575 0.4795 0.0251 0.9649 0.6393 0.4211
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
y_values = arrayfun(@(i)double(subs(y,[x1,x2,x3],[X(i,1),X(i,2),X(i,3)])),1:size(X,1))
y_values = 1x500
-0.2814 0.0388 -0.6179 0.0649 -0.5176 -0.5976 0.0616 0.1207 0.3824 0.0827 -0.0344 -0.2115 0.0699 -0.5435 -0.4269 -0.0763 -0.1279 -0.6958 -0.0936 -0.6281 -0.0479 -0.2730 0.1835 -0.0771 0.1207 0.3979 -0.1513 0.1458 -0.5483 -0.3726
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by