Use limit value at a point - matlab

I have the following lines of code
arg1 = ( x<=a ).*(log(x)) + ( x>a).*(log(2*a-x));
num = sinh(arg1);
den = const + cosh(arg1);
re = num./den + const2;
re1 = ;
But re is not defined at x=0, as log blows up at 0. But re has a limiting value at 0 which is defined as const3.
I want re1 as const3 when x=0 and as re when x>0.
I tried using piecewise as
re1:= piecewise([x = 0, const3],[ x>0, re]);
But this does not work.
I get the error "Undefined function or method re1 for input arguments of type char.
How should I get the desired result?

Just use logical indexing:
re1 = re;
re1(x == 0) = const3;
and, even though it's probably "impossible", my experience tells me it's a good idea to do this as well:
re1(x >= 2*a) = const3;

You will need Symbolic Math Toolbox.
In general, if you define f(x) as a function and want to calculate the limit at x=a, you do as follow,
sym x
const3 = limit (sym (f),x,a)
This might help: http://www.mathworks.in/help/symbolic/limit.html

Related

scipy.optimize failure with a "vectorized" implementation

I have an optimization problem (1d) coded in 2 ways - one using a for loop and an other using numpy arrays. The for loop version works fine but the numpy one fails.
Actually it is a bit more complicated, it can work with different starting points (!!) or if I choose an other optimization algo like CG.
The 2 versions (functions and gradients) are giving the same results and the returned types are also the same as far as I can tell.
Here is my example, what am I missing?
import numpy as np
from scipy.optimize import minimize
# local params
v1 = np.array([1., 1.])
v2 = np.array([1., 2.])
# local functions
def f1(x):
s = 0
for i in range(len(v1)):
s += (v1[i]*x-v2[i])**2
return 0.5*s/len(v1)
def df1(x):
g = 0
for i in range(len(v1)):
g += v1[i]*(v1[i]*x-v2[i])
return g/len(v1)
def f2(x):
return 0.5*np.sum((v1*x-v2)**2)/len(v1)
def df2(x):
return np.sum(v1*(v1*x-v2))/len(v1)
x0 = 10. # x0 = 2 works
# tests...
assert np.abs(f1(x0)-f2(x0)) < 1.e-6 and np.abs(df1(x0)-df2(x0)) < 1.e-6 \
and np.abs((f1(x0+1.e-6)-f1(x0))/(1.e-6)-df1(x0)) < 1.e-4
# BFGS for f1: OK
o = minimize(f1, x0, method='BFGS', jac=df1)
if not o.success:
print('FAILURE', o)
else:
print('SUCCESS min = %f reached at %f' % (f1(o.x[0]), o.x[0]))
# BFGS for f2: failure
o = minimize(f2, x0, method='BFGS', jac=df2)
if not o.success:
print('FAILURE', o)
else:
print('SUCCESS min = %f reached at %f' % (f2(o.x[0]), o.x[0]))
The error I get is
A1 = I - sk[:, numpy.newaxis] * yk[numpy.newaxis, :] * rhok
IndexError: invalid index to scalar variable.
but I doesn't really helps me since it can work with some other starting values.
I am using an all new fresh python install (python 3.5.2, scipy 0.18.1 and numpy 1.11.3).
The solver expects the return value of jacobian df2 to be the same shape as its input x. Even though you passed in a scalar here, it's actually converted into a single element ndarray. Since you used np.sum, your result became scalar and that causes strange things to happen.
Enclose the scalar result of df2 with np.array, and your code should work.

Use of if statement in for loop in this code

What does the statement for if=ilow:ihigh mean in this program?
function [d]=for_taup(m,dt,h,q,N,flow,fhigh);
nt= max(size(m));
nh = max(size(h));
M = fft(m,[],1);
D = zeros(nt,nh);
i = sqrt(-1);
ilow = floor(flow*dt*nt)+1; if ilow<1; ilow=1;end;
ihigh = floor(fhigh*dt*nt)+1;
if ihigh>floor(nt/2)+1; ihigh=floor(nt/2)+1;end
for if=ilow:ihigh
f = 2.*pi*(if-1)/nt/dt;
L = exp(i*f*(h.^N)’*q);
x = M(if,:)’;
y = L * x;
D(if,:) = y’;
D(nt+2-if,:) = conj(y)’;
end
D(nt/2+1,:) = zeros(1,nh);
d = real(ifft(D,[],1));
return;
if is used as a variable name. I am surprised that this does not raise a syntax error: most languages would forbid the use of "reserved" keywords. Maybe it would be a good idea to replace if with a different name in order to clarify your code and avoid confusion.
As far as MATLAB is concerned, this code doesn't really mean anything, because it's just a syntax error. if is reserved keyword, and you can't create a variable called if. As such, it just instantly errors and won't run.
You should probably replace all occurrences of the variable if (although not the keyword if in lines 8 and 10) with some other variable name. Avoid i, since you're using that as the imaginary unit.

Convert matlab symbol to array of products

Can I convert a symbol that is a product of products into an array of products?
I tried to do something like this:
syms A B C D;
D = A*B*C;
factor(D);
but it doesn't factor it out (mostly because that isn't what factor is designed to do).
ans =
A*B*C
I need it to work if A B or C is replaced with any arbitrarily complicated parenthesized function, and it would be nice to do it without knowing what variables are in the function.
For example (all variables are symbolic):
D = x*(x-1)*(cos(z) + n);
factoring_function(D);
should be:
[x, x-1, (cos(z) + n)]
It seems like a string parsing problem, but I'm not confident that I can convert back to symbolic variables afterwards (also, string parsing in matlab sounds really tedious).
Thank you!
Use regexp on the string to split based on *:
>> str = 'x*(x-1)*(cos(z) + n)';
>> factors_str = regexp(str, '\*', 'split')
factors_str =
'x' '(x-1)' '(cos(z) + n)'
The result factor_str is a cell array of strings. To convert to a cell array of sym objects, use
N = numel(factors_str);
factors = cell(1,N); %// each cell will hold a sym factor
for n = 1:N
factors{n} = sym(factors_str{n});
end
I ended up writing the code to do this in python using sympy. I think I'm going to port the matlab code over to python because it is a more preferred language for me. I'm not claiming this is fast, but it serves my purposes.
# Factors a sum of products function that is first order with respect to all symbolic variables
# into a reduced form using products of sums whenever possible.
# #params orig_exp A symbolic expression to be simplified
# #params depth Used to control indenting for printing
# #params verbose Whether to print or not
def factored(orig_exp, depth = 0, verbose = False):
# Prevents sympy from doing any additional factoring
exp = expand(orig_exp)
if verbose: tabs = '\t'*depth
terms = []
# Break up the added terms
while(exp != 0):
my_atoms = symvar(exp)
if verbose:
print tabs,"The expression is",exp
print tabs,my_atoms, len(my_atoms)
# There is nothing to sort out, only one term left
if len(my_atoms) <= 1:
terms.append((exp, 1))
break
(c,v) = collect_terms(exp, my_atoms[0])
# Makes sure it doesn't factor anything extra out
exp = expand(c[1])
if verbose:
print tabs, "Collecting", my_atoms[0], "terms."
print tabs,'Seperated terms with ',v[0], ', (',c[0],')'
# Factor the leftovers and recombine
c[0] = factored(c[0], depth + 1)
terms.append((v[0], c[0]))
# Combines trivial terms whenever possible
i=0
def termParser(thing): return str(thing[1])
terms = sorted(terms, key = termParser)
while i<len(terms)-1:
if equals(terms[i][1], terms[i+1][1]):
terms[i] = (terms[i][0]+terms[i+1][0], terms[i][1])
del terms[i+1]
else:
i += 1
recombine = sum([terms[i][0]*terms[i][1] for i in range(len(terms))])
return simplify(recombine, ratio = 1)

Evaluate function in Matlab

I am trying to evaluate the function in t = 1 in Matlab.
How can I get an answer to the following code ?
result = dsolve('D2y-23*Dy+22*y=sin(t)','y(0)=0','Dy(0)=0');
disp(result);
disp(fnval(result, 1));
The first answer is: exp(22*t)/10185 + (23*cos(t))/970 - exp(t)/42 + (21*sin(t))/970.
But when I am trying to find the evaluation of the function in the point t =1, the progrem is throwing some exception. Maybe the 'fnval' function is not suitable for here.
You can use subs.
result = dsolve('D2y-23*Dy+22*y=sin(t)','y(0)=0','Dy(0)=0');
t = 1;
subs(result)
ans =
3.5198e+005
You could also do it using eval, which is similar to your initial approach:
eval(result)
after assigning a value to t.
You can evaluate the function for a number range, using eval together with vectorize:
t = -0.1:0.01:0.1;
plot(t,eval(vectorize(result)))
This gives:

How do I get real integer overflows in MATLAB/Octave?

I'm working on a verification-tool for some VHDL-Code in MATLAB/Octave. Therefore I need data types which generate "real" overflows:
intmax('int32') + 1
ans = -2147483648
Later on, it would be helpful if I can define the bit width of a variable, but that is not so important right now.
When I build a C-like example, where a variable gets increased until it's smaller than zero, it spins forever and ever:
test = int32(2^30);
while (test > 0)
test = test + int32(1);
end
Another approach I tried was a custom "overflow"-routine which was called every time after a number is changed. This approach was painfully slow, not practicable and not working in all cases at all. Any suggestions?
In MATLAB, one option you have is to overload the methods that handle arithmetic operations for integer data types, creating your own custom overflow behavior that will result in a "wrap-around" of the integer value. As stated in the documentation:
You can define or overload your own
methods for int* (as you can for any
object) by placing the appropriately
named method in an #int* folder within
a folder on your path. Type help
datatypes for the names of the methods
you can overload.
This page of the documentation lists the equivalent methods for the arithmetic operators. The binary addition operation A+B is actually handled by the function plus(A,B). Therefore, you can create a folder called #int32 (placed in another folder on your MATLAB path) and put a function plus.m in there that will be used instead of the built-in method for int32 data types.
Here's an example of how you could design your overloaded plus function in order to create the overflow/underflow behavior you want:
function C = plus(A,B)
%# NOTE: This code sample is designed to work for scalar values of
%# the inputs. If one or more of the inputs is non-scalar,
%# the code below will need to be vectorized to accommodate,
%# and error checking of the input sizes will be needed.
if (A > 0) && (B > (intmax-A)) %# An overflow condition
C = builtin('plus',intmin,...
B-(intmax-A)-1); %# Wraps around to negative
elseif (A < 0) && (B < (intmin-A)) %# An underflow condition
C = builtin('plus',intmax,...
B-(intmin-A-1)); %# Wraps around to positive
else
C = builtin('plus',A,B); %# No problems; call the built-in plus.m
end
end
Notice that I call the built-in plus method (using the BUILTIN function) to perform addition of int32 values that I know will not suffer overflow/underflow problems. If I were to instead perform the integer addition using the operation A+B it would result in a recursive call to my overloaded plus method, which could lead to additional computational overhead or (in the worst-case scenario where the last line was C = A+B;) infinite recursion.
Here's a test, showing the wrap-around overflow behavior in action:
>> A = int32(2147483642); %# A value close to INTMAX
>> for i = 1:10, A = A+1; disp(A); end
2147483643
2147483644
2147483645
2147483646
2147483647 %# INTMAX
-2147483648 %# INTMIN
-2147483647
-2147483646
-2147483645
-2147483644
If you want to get C style numeric operations, you can use a MEX function to call the C operators directly, and by definition they'll work like C data types.
This method is a lot more work than gnovice's overrides, but it should integrate better into a large codebase and is safer than altering the definition for built-in types, so I think it should be mentioned for completeness.
Here's a MEX file which performs the C "+" operation on a Matlab array. Make one of these for each operator you want C-style behavior on.
/* c_plus.c - MEX function: C-style (not Matlab-style) "+" operation */
#include "mex.h"
#include "matrix.h"
#include <stdio.h>
void mexFunction(
int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
mxArray *out;
/* In production code, input/output type and bounds checks would go here. */
const mxArray *a = prhs[0];
const mxArray *b = prhs[1];
int i, n;
int *a_int32, *b_int32, *out_int32;
short *a_int16, *b_int16, *out_int16;
mxClassID datatype = mxGetClassID(a);
int n_a = mxGetNumberOfElements(a);
int n_b = mxGetNumberOfElements(b);
int a_is_scalar = n_a == 1;
int b_is_scalar = n_b == 1;
n = n_a >= n_b ? n_a : n_b;
out = mxCreateNumericArray(mxGetNumberOfDimensions(a), mxGetDimensions(a),
datatype, mxIsComplex(a));
switch (datatype) {
case mxINT32_CLASS:
a_int32 = (int*) mxGetData(a);
b_int32 = (int*) mxGetData(b);
out_int32 = (int*) mxGetData(out);
for (i=0; i<n; i++) {
if (a_is_scalar) {
out_int32[i] = a_int32[i] + b_int32[i];
} else if (b_is_scalar) {
out_int32[i] = a_int32[i] + b_int32[0];
} else {
out_int32[i] = a_int32[i] + b_int32[i];
}
}
break;
case mxINT16_CLASS:
a_int16 = (short*) mxGetData(a);
b_int16 = (short*) mxGetData(b);
out_int16 = (short*) mxGetData(out);
for (i=0; i<n; i++) {
if (a_is_scalar) {
out_int16[i] = a_int16[0] + b_int16[i];
} else if (b_is_scalar) {
out_int16[i] = a_int16[i] + b_int16[0];
} else {
out_int16[i] = a_int16[i] + b_int16[i];
}
}
break;
/* Yes, you'd have to add a separate case for every numeric mxClassID... */
/* In C++ you could do it with a template. */
default:
mexErrMsgTxt("Unsupported array type");
break;
}
plhs[0] = out;
}
Then you have to figure out how to invoke it from your Matlab code. If you're writing all the code, you could just call "c_plus(a, b)" instead of "a + b" everywhere. Alternately, you could create your own numeric wrapper class, e.g. #cnumeric, that holds a Matlab numeric array in its field and defines plus() and other operations that invoke the approprate C style MEX function.
classdef cnumeric
properties
x % the underlying Matlab numeric array
end
methods
function obj = cnumeric(x)
obj.x = x;
end
function out = plus(a,b)
[a,b] = promote(a, b); % for convenience, and to mimic Matlab implicit promotion
if ~isequal(class(a.x), class(b.x))
error('inputs must have same wrapped type');
end
out_x = c_plus(a.x, b.x);
out = cnumeric(out_x);
end
% You'd have to define the math operations that you want normal
% Matlab behavior on, too
function out = minus(a,b)
[a,b] = promote(a, b);
out = cnumeric(a.x - b.x);
end
function display(obj)
fprintf('%s = \ncnumeric: %s\n', inputname(1), num2str(obj.x));
end
function [a,b] = promote(a,b)
%PROMOTE Implicit promotion of numeric to cnumeric and doubles to int
if isnumeric(a); a = cnumeric(a); end
if isnumeric(b); b = cnumeric(b); end
if isinteger(a.x) && isa(b.x, 'double')
b.x = cast(b.x, class(a.x));
end
if isinteger(b.x) && isa(a.x, 'double')
a.x = cast(a.x, class(b.x));
end
end
end
end
Then wrap your numbers in the #cnumeric where you want C-style int behavior and do math with them.
>> cnumeric(int32(intmax))
ans =
cnumeric: 2147483647
>> cnumeric(int32(intmax)) - 1
ans =
cnumeric: 2147483646
>> cnumeric(int32(intmax)) + 1
ans =
cnumeric: -2147483648
>> cnumeric(int16(intmax('int16')))
ans =
cnumeric: 32767
>> cnumeric(int16(intmax('int16'))) + 1
ans =
cnumeric: -32768
There's your C-style overflow behavior, isolated from breaking the primitive #int32 type. Plus, you can pass a #cnumeric object in to other functions that are expecting regular numerics and it'll "work" as long as they treat their inputs polymorphically.
Performance caveat: because this is an object, + will have the slower speed of a method dispatch instead of a builtin. If you have few calls on large arrays, this'll be fast, because the actual numeric operations are in C. Lots of calls on small arrays, could slow things down, because you're paying the per method call overhead a lot.
I ran the following snippet of code
test = int32(2^31-12);
for i = 1:24
test = test + int32(1)
end
with unexpected results. It seems that, for Matlab, intmax('int32')+1==intmax('int32'). I'm running 2010a on a 64-bit Mac OS X.
Not sure that this as an answer, more confirmation that Matlab behaves counterintuitively. However, the documentation for the intmax() function states:
Any value larger than the value returned by intmax saturates to the intmax value when cast to a 32-bit integer.
So I guess Matlab is behaving as documented.
Hm, yes...
Actually, I was able to solve the problem with my custom "overflow"-Subroutine... Now it runs painfully slow, but without unexpected behaviour! My mistake was a missing round(), since Matlab/Octave will introduce small errors.
But if someone knows a faster solution, I would be glad to try it!
function ret = overflow_sg(arg,bw)
% remove possible rounding errors, and prepare returnvalue (if number is inside boundaries, nothing will happen)
ret = round(arg);
argsize = size(ret);
for i = 1:argsize(1)
for j = 1:argsize(2)
ret(i,j) = flow_sg(ret(i,j),bw);
end
end
end%function
%---
function ret = flow_sg(arg,bw)
ret = arg;
while (ret < (-2^(bw-1)))
ret = ret + 2^bw;
end
% Check for overflows:
while (ret > (2^(bw-1)-1))
ret = ret - 2^bw;
end
end%function
If 64 bits is enough to not overflow, and you need a lot of these, perhaps do this:
function ret = overflow_sg(arg,bw)
mask = int64(0);
for i=1:round(bw)
mask = bitset(mask,i);
end
topbit = bitshift(int64(1),round(bw-1));
subfrom = double(bitshift(topbit,1))
ret = bitand( int64(arg) , mask );
i = (ret >= topbit);
ret(i) = int64(double(ret(i))-subfrom);
if (bw<=32)
ret = int32(ret);
end
end
Almost everything is done as a matrix calculation, and a lot is done with bits, and everything is done in one step (no while loops), so it should be pretty fast. If you're going to populate it with rand, subtract 0.5 since it assumes it should round to integer values (rather than truncate).
I'm not a Java expert, but underlying Java classes available in Matlab should allow handling of overflows like C would. One solution I found, works only for single value, but it converts a number to the int16 (Short) or int32 (Integer) representation. You must do your math using Matlab double, then convert to Java int16 or int32, then convert back to Matlab double. Unfortunately Java doesn't appear to support unsigned types in this way, only signed.
double(java.lang.Short(hex2dec('7FFF')))
<br>ans = 32767
double(java.lang.Short(hex2dec('7FFF')+1))
<br>ans = -32768
double(java.lang.Short(double(intmax('int16'))+1))
<br>ans = -32768
double(java.lang.Integer(hex2dec('7FFF')+1))
<br>ans = 32768
https://www.tutorialspoint.com/java/lang/java_lang_integer.htm