I want to see how Maple determined the type of an ODE. But can't set break point at internal Maple proc:
restart;
ode:=2*sqrt(a*diff(y(x),x))+x*diff(y(x),x)-y(x) = 0;
DEtools:-odeadvisor(ode);
#[[_homogeneous, `class G`], _Clairaut]
But when I do
stopat(DEtools:-odeadvisor);
it gives erorr
Error, invalid input: stopat expects its 1st argument, p, to be of type {`::`, name, string}, but received proc () option `Copyright (c) 1997 Waterloo Maple Inc. All rights reserved.`; `ODEtools/initialized` <> 'true' and `ODEtools/init`() <> 0; `ODEtools/odeadv`(args) end proc
Is it possible to set break point at DEtools:-odeadvisor? showstat does not show much. I thought it was possible to view all Maple library code (other than the builtin ones).
But may be some are not possible to see in addition to the builtin? How does one know then which one can see and which one can't see? How one see the code the DEtools:-odeadvisor?
Maple 2018.1
Try this,
restart;
ode:=2*sqrt(a*diff(y(x),x))+x*diff(y(x),x)-y(x) = 0:
showstat(DEtools[odeadvisor]);
stopat(`ODEtools/odeadv`);
DEtools:-odeadvisor(ode);
Related
So I am making a program that checks if a number is divisible by another number or not. If it is its supposed to return true, otherwise false. Here's what I have so far.
P.S : I'm using IBM (GnuCOBOL v2.2 -std=ibm-strict -O2) to run this.
IDENTIFICATION DIVISION.
PROGRAM-ID. CHECKER.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BASE PIC 9(5).
01 FACTOR PIC 9(2).
01 RESULT PIC 9(5).
88 TRU VALUE 0 .
88 FAL VALUE 1 THRU 99 .
PROCEDURE DIVISION.
CHECK-FOR-FACTOR SECTION.
IF FUNCTION MOD(BASE, FACTOR) = 0 THEN
SET TRU TO TRUE
ELSE
SET FAL TO TRUE
END-IF.
END PROGRAM CHECKER.
It gives me error saying invalid use of level 88. I'm sure I'm making a mistake, and I've searched for couple of days and I can't seem to find anything that can help me with it. Any ideas if it is possible in COBOL or does COBOL handle all the boolean stuff some other way ?
(Kindly do not reply with look up level 88 or some other stuff like that, I have already looked them up and they haven't been helping)
To return TRUE from a program you'd need an implementation that has boolean USAGE, define that in LINKAGE and specify it in PROCEDURE-DIVISION RETURNING true-item and also use CALL 'yourprog' RETURNING true-item.
Your specified environment GnuCOBOL doesn't have a boolean USAGE in 2021 and can't handle RETURNING phrase of PROCEDURE DIVISION in programs.
But you can use a very common extension to COBOL which is available in both IBM and GnuCOBOL:
Before the program ends MOVE RESULT TO RETURN-CODE (which is a global register) and in the calling program check its value (and reset it to zero).
Then it is only up to you what value means "true" (in your program it is 0).
As an alternative you could create a user-define function (FUNCTION-ID instead of PROGRAM-ID and use the RETURNING phrase to pass your result) - but that would mean you need to use IF FUNCTION instead of CALL + IF RETURN-CODE in each caller.
I have an unformatted binary file generated using the Compaq Visual Fortran compiler (big endian).
Here's what the little bit of documentation states about it:
The binary file is written in a general format consisting of data arrays, headed by a descriptor record:
An 8-character keyword which identifies the data in the block.
A 4-byte signed integer defining the number of elements in the block.
A 4-character keyword defining the type of data. (INTE, REAL, LOGI, DOUB, or CHAR)
The header items are read in as a single record. The data follows the descriptor on a new record. Numerical arrays are divided into block of up to 1000 items. The physical record size is the same as the block size.
Attempts to read such data
module modbin
type rectype
character(len=8)::key
integer::data_count
character(len=4)::data_type
logical::is_int
integer, allocatable:: idata(:)
real(kind=8), allocatable::rdata(:)
end type
contains
subroutine rec_read(in_file, out_rec)
integer, intent(in):: in_file
type (rectype), intent(inout):: out_rec
!
! You need to play around with this figure. It may not be
! entirely accurate - 1000 seems to work, 1024 does not
integer, parameter:: bsize = 1000
integer:: bb, ii, iimax
! read the header
out_rec%data_count = 0
out_rec%data_type = ' '
read(in_file, end = 20) out_rec%key, out_rec%data_count,
out_rec%data_type
! what type is it?
select case (out_rec%data_type)
case ('INTE')
out_rec%is_int = .true.
allocate(out_rec%idata(out_rec%data_count))
case ('DOUB')
out_rec%is_int = .false.
allocate(out_rec%rdata(out_rec%data_count))
end select
! read the data in blocks of bsize
bb = 1
do while (bb .lt. out_rec%data_count)
iimax = bb + bsize - 1
if (iimax .gt. out_rec%data_count) iimax = out_rec%data_count
if (out_rec%is_int) then
read(in_file) (out_rec%idata(ii), ii = bb, iimax)
else
read(in_file) (out_rec%rdata(ii), ii = bb, iimax)
end if
bb = iimax + 1
end do
20 continue
end subroutine rec_read
subroutine rec_print(in_recnum, in_rec)
integer, intent(in):: in_recnum
type (rectype), intent(in):: in_rec
print *, in_recnum, in_rec%key, in_rec%data_count, in_rec%data_type
! print out data
open(unit=12, file='reader.data' , status='old')
write(12,*)key
!write(*,'(i5')GEOMINDX
!write(*,'(i5')ID_BEG
!write(*,'(i5')ID_END
!write(*,'(i5')ID_CELL
!write(*,'(i5')TIME_BEG
!write(*,'(i5')SWAT
!format('i5')
!end do
close(12)
end subroutine rec_print
end module modbin
program main
use modbin
integer, parameter:: infile=11
! fixed size for now - should really be allocatable
integer, parameter:: rrmax = 500
type (rectype):: rec(rrmax)
integer:: rr, rlast
open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED',
status='OLD', convert='BIG_ENDIAN')
rlast = 0
do rr = 1, rrmax
call rec_read(infile, rec(rr))
if (rec(rr)%data_type .eq. ' ') exit
rlast = rr
call rec_print(rr, rec(rr))
end do
close(infile)
end program main
This code compiles and runs smoothly showing
and produces no errors but this is written in the output file
shows me no useful numerical values
The file in question is available here
And the right WRITE statement should produce a file like this one here
Is my WRITE STATEMENT to output this file type wrong? , and if so, what is the best way?
thank you
The comments above are trying to direct you to one of (at least) two problems in your code. In the subroutine rec_print you have write(12,*)key where you meant to write write(12,*)in_rec%key (at least I think that's what you wanted.)
The other problem I spotted is that rec_print opens reader.data with status='old' and then closes it after writing key. (The use of old here suggests that the file already exists.) Each time rec_print is called, the file is opened, the first record is overwritten, and the file is closed. One solution to this would be to use status='unknown'. position='append', though it would be more efficient to open the file once in the main program and just let the subroutine write to it.
If I make these changes, I get in the data file:
INTEHEAD
GEOMETRY
GEOMINDX
ID_BEG
ID_END
ID_CELL
TIME_BEG
SWAT
A side-comment about CONVERT= and derived types: Your program isn't affected by this, but there are compiler differences with how reading a derived type record with CONVERT= is handled. I think gfortran converts each component according to its type, but I know that Intel Fortran doesn't convert reads (nor writes) of an entire derived type. You are reading individual components, which works in both compilers, so that's fine, but I thought it was worth mentioning.
If you're wondering why Intel Fortran does it this way, it's due to the VAX FORTRAN (where CONVERT= came from) heritage with STRUCTURE/RECORD and the possible use of UNION/MAP (not available in standard Fortran). With unions, there's no way to know how a particular component should be converted, so it just transfers the bytes. I had suggested to the Intel team that this could be relaxed if no UNIONs were present, but that I'm sure is very low priority.
In the Excel VBA Editor's Immediate Window, I can do the following:
?ActiveSheet.Range("C3:D4").Range("C3:D4").Address
$E$5:$F$6
According to some simple tests, this doesn't seem to respond the same in Matlab. Here is the code to set up the COM interface for the tests:
excel = actxserver('Excel.Application');
excel.Visible=1;
wbks = excel.Workbooks;
wbks.Add
sht = wbks.Item(1).Sheets.Item(1)
%
% Run some range tests
%
try
excel.DisplayAlerts = 0; % Forgo save prompt on Close
end; try
wbk.Close
end; try
excel.Quit % Excel process still present
end; try
delete(excel) % Excel process disappears
end % try
Now, with sht being a Worksheet object, I get the following error instead:
K>> o=sht.Range('C3:D4')
o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o.Range('C3:D4').Address
Cannot find an exact (case-sensitive) match for 'Range'
The closest match is: range in C:\Program Files\MATLAB\Single_R2015b\toolbox\stats\stats\range.m
Did you mean: K>> o.range('C3:D4').Address
This is the wrong function, since range with an uncapitalized r is the internal Matab function. Hence, I pressed Ctrl-C to break out (otherwise, it complains about the incompatible argument).
To troubleshoot why Range is not recognized, check whether is is a method or property. When accessed via COM, Range is a method rather than a property:
K>> methods(o)
Methods for class Interface.Microsoft_Excel_14.0_Object_Library.Range:
<...snip...>
PrintPreview Table
Range TextToColumns
RemoveDuplicates UnMerge
<...snip...>
This further shows that Range is not a property (even though it is in VBA):
K>> get(o)
<...snip...>
QueryTable: 'Error: Object returned error code: 0x800A03EC'
Resize: [1x1 Interface.Microsoft_Excel_14.0_Object_Library.Range]
Row: 3
<...snip...>
Since properties are listed alphabetically, Range would show up after QueryTable if it was recognized as a property. However, it isn't listed in the above results.
As an alternative diagnostic step, I tried accessing Range using the dot notation (o.Range). Unfortunately, Matlab seems to got for its own native function range, which has nothing to do with an Excel Range.
So after all that diagnostic work....
THE QUESTION
For a given Range object, how does one access the Range method (as recognized by COM) or the Range property (as it is described in the VBA documentation)?
AFTERNOTE
There seem to be many discrepancies with in accessing Range properties and methods via the COM interface. In the Immediate Window, one can use the Offset property (it is desribed as a property):
? ActiveSheet.Range("C3:D4").Offset(2,3).Address
$F$5:$G$6
Over COM, not so much, even though get(o) shows Offset to be a valid property that returns a range:
K>> o=sht.Range('C3:D4')
o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o=o.Offset(2,2)
Index exceeds matrix dimensions.
Here is a solution I've reached by trial and error, refined with some help with Matlab technical support:
Invoke get as a method, then supply the desired property name. It works for property Offset.
K>> o = sht.Range('C3:D4')
o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o.get('Offset',2,3).Address
ans = $F$5:$G$6
It works for Range, too.
K>> o = sht.Range('C3:E5')
o = Interface.Microsoft_Excel_14.0_Object_Library.Range
K>> o.get('Range','B2:C3').Address
ans = $D$4:$E$5
The strange thing is that Range is a method according to COM (but a property according to the Excel VBA documentation). Despite being seen as a method when accessed via COM, it needs to be invoked using get rather than invoke. The latter yields an error:
K>> o.invoke('Range','B2:C3').Address
Error using Interface.Microsoft_Excel_14.0_Object_Library.Range/invoke.
Cannot find an exact (case-sensitive) match for 'Range'.
The closest match is: range in C:\Program Files\MATLAB\Single_R2015b\toolbox\stats\stats\range.m
Actually I am coding a Matlab simulation where the AnchorID and SourceID will report to eachother. For example if I take an anchor 30 and source 50 it will collect all the agc values between these anchor and source and calculate rssi_dB and display them.Below mentioned is an example of anchor 30 and source id 50
Note: list of anchors ID's and source ID's are same. for e.g. 30 50 55 58 . These ID are both same for anchor and source.
function A30(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=30;
xSourceID=50;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call the function in Matlab command window I get the rssi value of the above function.
Also my task is when I reciprocate the Anchor ID and source ID say Anchor as 50 and source as 30 like the function I have mentioned below I get an error which is mentioned after the function below.
function A50(BlinkSet)
for i=1:length(BlinkSet)
xAnchorID=50;
xSourceID=30;
a=BlinkSet{i}.AnchorID;
b=BlinkSet{i}.SourceID;
if xAnchorID==a && xSourceID==b
xagc=BlinkSet{i}.agc;
rssi_dB(i)=-(33+xagc*(89-33)/(29-1));
end
end
rssi_dB(rssi_dB==0)=[];
rssi_dBm=sum(rssi_dB(:))/length(rssi_dB);
disp([sprintf('The rssi value is %0.0f',rssi_dBm)]);
When I call this function I get an error as
??? Undefined function or variable "rssi_dB".
Error in ==> A50 at 14
rssi_dB(rssi_dB==0)=[];
Error in ==> main_reduced at 26
A50(BlinkSet);
In main function I have coded like this,
%A30(BlinkSet);
A50(BlinkSet);
Any help is highly appreciated.
In both of these functions, you only create the variable rssi_dB if execution enters the if statement within the loop (i.e., if xAnchorID==a && xSourceID==b is at some point true). Clearly, this code is never executed in your A50 function. Without knowing what is in BlinkSet it's a bit difficult to diagnose the exact problem, but this is the cause at least.
As a side note: it's not a good idea to create two separate functions to do this job when their code is almost identical. You should add an input argument to your function that allows it to do the job of both. In this particular case, all that changes is the value of xAnchorID and xSourceID, so you could just pass these in:
function srcToAnchorRssi(BlinkSet, xSourceID, xAnchorID)
% The rest of the function stays the same!
If you want to provide some defaults for these arguments, you can do, e.g.:
if nargin < 3 || isempty(xAnchorID), xAnchorID = 50; end
if nargin < 2 || isempty(xSourceID), xSourceID = 30; end
It's always a good idea to include an isempty in statements of this sort, so that your function supports syntax like myFunction(myArg1, [], myArg3). Also note that the order of the operands to || is crucial; if you did if isempty(theArgument) || nargin < theArgumentNumber and the user did not pass theArgument, then it would error in the isempty because theArgument would not exist as a local variable. We can get around this by swapping the operands' order because MATLAB is smart enough to know it doesn't have to evaluate the right operand if the left operand is true (note that this is also the case in many other programming languages).
I have written this function, and I have already defined values for rg and Lp, but still when I run this function it returns the error : (Input argument "Lr" is undefined.
Error in ==> Bis at 12
if f(Lr,rg,Xo)*f(Lr,rg,Xf)>0)
here is the function :
function[Lp,Xo,Xf]=Bis(Lr,rg)
Xo=0;
Xf=10;
Err=0.01;
syms x;
f=inline('(sqrt((2/3)*(((x*Lr)/3)-(x*x)+((2*x*x*x)/Lr)-((2*x*x*x*x)/(Lr*Lr))+(((2*x*x*x*x)/(Lr*Lr))*exp(-Lr/x))))-rg)');
if f(Lr,rg,Xo)*f(Lr,rg,Xf)>0
disp('The values you entered are not apropriate !')
PlotLpFunction;
Lp='unknown';
elseif f(Lr,rg,Xo)*f(Lr,rg,Xf)==0
if f(Lr,rg,Xo)==0
Lp=Xo;
elseif f(Lr,rg,Xf)==0
Lp=Xf;
end
elseif f(Lr,rg,Xo)*f(Lr,rg,Xf)<0
xi=(Xf-Xo)/2;
while abs(f(Lr,rg,xi))>Err
if f(Lr,rg,xi)*f(Lr,rg,Xf)<0
Xo=xi;
xi=(Xo+Xf)/2;
elseif f(Lr,rg,xi)*f(Lr,rg,Xf)>0
Xf=xi;
xi=(Xo+Xf)/2;
end
end
Lp=xi;
end
The code executes for me on the newest version of Matlab, other than the fact that I don't have the PlotLpFunction.
My initial impression was that you forgot to send the Lr (and all other argument) into you're inlined f function, very easy to fix by adding them as arguments to the inline function. You'll find the full usage in the official documentation.
The relevant part being
inline(expr,arg1,arg2,...) constructs an inline function whose input
arguments are specified by the strings arg1, arg2,.... Multicharacter
symbol names may be used.
but it seems to form the inline just fine by itself on both Matlab 2011b and 2008b, from context presumably. Answer is accepted now, so presumably that was the problem. Can anyone else reproduce his problem? If so please provide your Matlab version or other circumstances.