Manipulating a text file without using symbolic engine

1 visualización (últimos 30 días)
Hello friends!
I have extremely long algebraic expressions saved as text files. I need to asign 0 to some variables in the text file and
find a way to simplify it. Of course I can use symbolic engine but I do not dare to do this simply beacause it takes ages
to do so. So, I wish to do this special simplification by text manipulation only. To make it clear, let's go for a simple example as bellow:
str='-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24';
Now, if D2=0 then str should be simplified to
str='-(dt^(1/2)*(24*D0+dt*(dt*(D4+4*D0*D1^2+4*D0*D3)+12*D0*D1)))/24';
Any idea?
Your help is greatly apreciated!
Babak
  11 comentarios
DGM
DGM el 25 de Dic. de 2021
Editada: DGM el 25 de Dic. de 2021
That's not simplification. That's merely substitution, and it's not what your initial example describes.
If substitution is sufficient, that can be done with strrep()
tosub = 'D2';
orig = '-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24';
example = '-(dt^(1/2)*(24*D0+dt*(dt*(D4+4*D0*D1^2+4*D0*D3)+12*D0*D1)))/24';
subsonly = strrep(orig,tosub,'0')
subsonly = '-(dt^(1/2)*(24*D0+dt*(6*0+dt*(D4+4*D0*D1^2+4*D0^2*0+4*D0*D3+6*D1*0)+12*D0*D1)))/24'
but it's not clear that such a minor change actually saves any significant amount of time, as no simplification occurs.
syms dt D0 D1 D2 D3 D4
orig = '-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24';
orig = [orig '+' orig '+' orig '+' orig '+' orig]; % make it longer
orig = [orig '*' orig '*' orig '*' orig '*' orig];
numel(orig)
ans = 2149
timeit(@() symbolicmethod(orig,D2))
ans = 2.7823
timeit(@() stringmethod(orig))
ans = 2.6660
function symbolicmethod(orig,D2)
origsym = str2sym(orig); % convert to sym
symsubs = subs(origsym,D2,0); % substitute and simplify
end
function stringmethod(orig)
strsubs = strrep(orig,'D2','0'); % string substitution with no simplification
strsubs = str2sym(strsubs); % convert to sym and simplify
end
The two results symsubs and strsubs are identical, but the speed advantage of case 2 in this example is pretty small. It's small enough that it's occasionally slower than case 1. Can it be made faster? I don't know. Is it better with particular expressions? I don't know.
Walter Roberson
Walter Roberson el 25 de Dic. de 2021
str='-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24';
Now, if D2=0 then str should be simplified to
str='-(dt^(1/2)*(24*D0+dt*(dt*(D4+4*D0*D1^2+4*D0*D3)+12*D0*D1)))/24';
Matching parts, we see that the simplified string has transformed +6*D1*D2 to nothing, and 6*D2+ to nothing, and +D0^2*D2 to nothing . So the D2 has to be recognized in the leading term of a summation, and in the trailing term of a summation, and terms that include an addend that has a multiplication by D2 are to vanish, at least in the case where the D2 is the final multiplication in the term (we do not have an example to go by to tell whether the term needs to vanish if D2 appears anywhere else in the term.)
D0*(D1 + D2) + D0*D1 = D0*(D1+0)
D0/D2 = D0/0
3*(D2 + 1) + 4 = 3*(0+1)
According to the first of those, D2 is to become 0 but the 0 is to stay in the addition. What is different about this case compared to the earlier cases where the term vanished? Well in this case, D2 is not being multiplied by anything. So we deduce that terms should only vanish in an addend if the component that is becoming 0 is the final factor in the multiplication.
According to the second of those, 0 as a pure denominator does not need to vanish. I did not thing to ask about the case of D0 + D2/5 where the 0 would be a pure numerator . I also did not think to ask about D0 + D1*D2/5 or D0 + D2*D1/5
According to the third of those, the D2 is to become 0 but the 0 is to stay in the addition. What is different about this case compared to the earlier cases where the term vanished? Well in this case, D2 is not being multiplied by anything. So we deduce that terms should only vanish in an addend if the component that is becoming 0 is the final factor in the multiplication.
But... in the third of those, we also see that the + 4 is intended to vanish. The reason for that is not obvious at all. I cannot come up with any rule about that.
It would be a lot easier on us if you were to give us a list of replacement rules instead of requiring us to give examples and you tell us what result you want for the example.
If I had not asked about those examples, I would have had no way of knowing that you want the 0+ or +0 to stay when the variable appears by itself in an addend.

Iniciar sesión para comentar.

Respuesta aceptada

Walter Roberson
Walter Roberson el 25 de Dic. de 2021
Sorry, I can't be bothered to preserve spaces. Also, without authorization, I went ahead and surpressed multiplication by 1 (but not division by 1)
str = ["-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24"
"-(dt^(1/2)*(24*D0-dt*(6*D2-dt*(D4-4*D0*D1^2-4*D0^2*D2-4*D0*D3-6*D1*D2)-12*D0*D1)))/24"
"D0*(D1 + D2) + D0*D1"
"D0/D2 - D1*D0 + D1*12 - 12*D1 + 13*D0 - D0*13"
"3*(D2 + 1) + 4"]
str = 5×1 string array
"-(dt^(1/2)*(24*D0+dt*(6*D2+dt*(D4+4*D0*D1^2+4*D0^2*D2+4*D0*D3+6*D1*D2)+12*D0*D1)))/24" "-(dt^(1/2)*(24*D0-dt*(6*D2-dt*(D4-4*D0*D1^2-4*D0^2*D2-4*D0*D3-6*D1*D2)-12*D0*D1)))/24" "D0*(D1 + D2) + D0*D1" "D0/D2 - D1*D0 + D1*12 - 12*D1 + 13*D0 - D0*13" "3*(D2 + 1) + 4"
strs = regexprep(str, '\s', '');
str0 = regexprep(strs, {'\<D2\>', '\<D0\>'}, {'0', '1'})
str0 = 5×1 string array
"-(dt^(1/2)*(24*1+dt*(6*0+dt*(D4+4*1*D1^2+4*1^2*0+4*1*D3+6*D1*0)+12*1*D1)))/24" "-(dt^(1/2)*(24*1-dt*(6*0-dt*(D4-4*1*D1^2-4*1^2*0-4*1*D3-6*D1*0)-12*1*D1)))/24" "1*(D1+0)+1*D1" "1/0-D1*1+D1*12-12*D1+13*1-1*13" "3*(0+1)+4"
strnz = regexprep(str0, {'[+-]\<[a-zA-Z0-9\*\^]+\*0', '\<[a-zA-Z0-9\*\^]+\*0\+', '\<[a-zA-Z0-9\*\^]+\*0\-'}, {'', '', '-'})
strnz = 5×1 string array
"-(dt^(1/2)*(24*1+dt*(dt*(D4+4*1*D1^2+4*1*D3)+12*1*D1)))/24" "-(dt^(1/2)*(24*1-dt*(-dt*(D4-4*1*D1^2-4*1*D3)-12*1*D1)))/24" "1*(D1+0)+1*D1" "1/0-D1*1+D1*12-12*D1+13*1-1*13" "3*(0+1)+4"
strn1 = regexprep(strnz, {'\*1\>', '\<1\*'}, {'', ''})
strn1 = 5×1 string array
"-(dt^(1/2)*(24+dt*(dt*(D4+4*D1^2+4*D3)+12*D1)))/24" "-(dt^(1/2)*(24-dt*(-dt*(D4-4*D1^2-4*D3)-12*D1)))/24" "(D1+0)+D1" "1/0-D1+D1*12-12*D1+13-13" "3*(0+1)+4"
  4 comentarios
Mohammad Shojaei Arani
Mohammad Shojaei Arani el 27 de Dic. de 2021
Thanks Walter for your precious time. I will have to find a way for this.
Walter Roberson
Walter Roberson el 27 de Dic. de 2021
Do you have situations where you have ^ with the power being a variable ?
... Because if you do not, then I am not going to bother to write up a solution.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Logical en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by